php guzzle发送异步请求问题

use GuzzleHttp\Client;
use GuzzleHttp\Handler\CurlMultiHandler;
use GuzzleHttp\HandlerStack;
use Psr\Http\Message\ResponseInterface;

$curl = new CurlMultiHandler;
$handler = HandlerStack::create($curl);
$client = new Client(['handler' => $handler]);

$client
    ->getAsync('http://google.com')
    ->then(
        function (ResponseInterface $res) {
            echo 'response: ' . $res->getStatusCode() . PHP_EOL;
        },
        function (\Exception $e) {
            echo $e->getMessage() . PHP_EOL;
        }
    )
    // ->wait()
    ;
$curl->tick();
echo 'bottom' . PHP_EOL;

使用guzzle发送异步请求返回的promise 调用 then 方法不会立即执行, 还必须要调用wait去等待所有的请求结束,才会执行这样整个文件的输出还是会被block,那这里的异步具体指的是什么?

阅读 19k
4 个回答

谢邀。
以下是个人想法,不一定对。

你可以访问 baidu.com | google.com 看看效果。
同步的写法是 1、baidu.com 返回结果了 =》2、去请求 google.com 等待返回结果
异步是 同时 访问 baidu.com | google.com ,不用被另一个请求卡住。
这就是区别。

作为整个程序来说,肯定是要全部执行完才会结束。

Concurrent requests章节说了:You can send multiple requests concurrently using promises and asynchronous requests.
根据异步并发的示例可以看出:
示例:假设有3的请求A,B,C,一般情况下只能A请求完了,再请求B,接着请求C(时间消耗是三者请求响应时间之和!!),使用该特性同时请求A,B,C,然后使用$results = Promise\settle($promises)->wait();来接受结果(时间消耗是三个请求响应最长的时间)
原理:至于如何实现异步请求的,可以查看guzzlehttp/promises这个包(源码我还没看到这个包,看完了再补充吧),这个特性和nodejs的async/wait、go的协程类似,猜测这个包也是使用了php的协程来完成的。
使用场景:见示例,你可以自己写一个异步网页爬虫,就能对此特性够有所体会了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏