24

With Guzzle, do promises provide any real utility? It seems that you must call wait(). The following code (from the docs) seems to do nothing by itself:

$promise = $client->requestAsync('GET', 'http://httpbin.org/get');
$promise->then(
    function (ResponseInterface $res) {
        echo $res->getStatusCode() . "\n";
    },
    function (RequestException $e) {
        echo $e->getMessage() . "\n";
        echo $e->getRequest()->getMethod();
    }
);

If you must call $promise->wait() to make the request, what's the point of a promise? How is this really any different than:

$request = new Request('GET', 'http://httpbin.org/get');
$response = $client->send($request); 

if ($response

Best I can tell, the only benefit is it's convenient approach to define the request success and failure callbacks. Even the doc section on making multiple requests has the code below, which appears to block and execute all requests... perhaps at the "same time". Is this all I should expect?

// Wait on all of the requests to complete.
$results = Promise\unwrap($promises);
originalbryan
  • 1,027
  • 1
  • 13
  • 21
  • 1
    Is async exactly synonymous with deferred processing? – Jared Farrish Mar 21 '16 at 23:04
  • Good question and probably not. Really I'm more confused by the promise part of it though. – originalbryan Mar 21 '16 at 23:20
  • I don't believe that PHP is capable of truly asynchronous event handling (yet), hence the call to `wait()`. So there may be some truth that some of the benefits you'd see in Javascript aren't evident in PHP's version of it (yet), but the purpose of a promise is that you can pass around a "read-only" like interface into the deferred that can't be resolved through that interface. Maybe this is for backwards compatibility (for now). – Jared Farrish Mar 21 '16 at 23:32

2 Answers2

14

I'm going out on a limb here, but from what I've read...

While PHP can't do asynchronous processing, you can open several streams and deal with their input without blocking. So in your example with a single connection, yes, there's no point/benefit.

But let's say you wanted to load up 5 resources. Using the async methods could enable these resources to load essentially in parallel - rather than only starting the 2nd one when the 1st one has loaded.

And Guzzle provides ways to handle use cases like "after they've all loaded correctly then..." or "after they've all either loaded or failed...".

So I think it should enable faster processing when handling multiple requests that can happen concurrently.

artfulrobot
  • 20,637
  • 11
  • 55
  • 81
4

Async requires a bit of reverse thinking.

Here is a scenario that may arise that might be useful: Given an API (http://ipsum.org/) you are require to get a list of data back (by id) to your route (or script) - If you do it procedural, you will have to loop through each request and wait till it all comes back.

With Guzzle Promise, you can "prep" for the response and then when it comes back - you can process it. The advantage of this is that instead of N request x T time of request in order to execute your script, the latency is now CEIL (slowest response time of all response received) as you "wait" for ALL responses to come back but they are sent in Parallel instead.

In other words, you are sending request in Parallel instead of serial so that you wait for the response to comeback OR you can pre-execute the curl call first, and then do a setup to "ok while I wait for the return, let me prepare the response".

The later part will require some restructuring since we are used to "go fetch, wait, then with answer back, we can operate on the response"

azngunit81
  • 1,574
  • 2
  • 20
  • 38