Using Guzzle promises asyncronously

Rich picture Rich · May 23, 2016 · Viewed 15.6k times · Source

I am attempting to use guzzle promises in order to make some http calls, to illustrate what I have, I have made this simple example where a fake http request would take 5 seconds:

$then = microtime(true);

$promise = new Promise(
    function() use (&$promise) {
        //Make a request to an http server
        $httpResponse = 200;
        sleep(5);
        $promise->resolve($httpResponse);
    });

$promise2 = new Promise(
    function() use (&$promise2) {
        //Make a request to an http server
        $httpResponse = 200;
        sleep(5);
        $promise2->resolve($httpResponse);
    });

echo 'PROMISE_1 ' . $promise->wait();
echo 'PROMISE_2 ' . $promise2->wait();

echo 'Took: ' . (microtime(true) - $then);

Now what I would want to do is start both of them, and then make both echo's await for the response. What actually happens is promise 1 fires, waits 5 seconds then fires promise 2 and waits another 5 seconds.

From my understanding I should maybe be using the ->resolve(); function of a promise to make it start, but I dont know how to pass resolve a function in which I would make an http call

Answer

Digital Chris picture Digital Chris · May 23, 2016

By using wait() you're forcing the promise to be resolved synchronously: https://github.com/guzzle/promises#synchronous-wait

According to the Guzzle FAQ you should use requestAsync() with your RESTful calls:

Can Guzzle send asynchronous requests?

Yes. You can use the requestAsync, sendAsync, getAsync, headAsync, putAsync, postAsync, deleteAsync, and patchAsync methods of a client to send an asynchronous request. The client will return a GuzzleHttp\Promise\PromiseInterface object. You can chain then functions off of the promise.

$promise = $client->requestAsync('GET', 'http://httpbin.org/get');
$promise->then(function ($response) {
echo 'Got a response! ' . $response->getStatusCode(); });

You can force an asynchronous response to complete using the wait() method of the returned promise.

$promise = $client->requestAsync('GET', 'http://httpbin.org/get');
$response = $promise->wait();