Guzzle异步承诺的意义何在?

2022-08-30 17:52:51

对于Guzzle,承诺是否提供了任何真正的效用?看来你必须调用wait()。以下代码(来自文档)本身似乎不执行任何操作:

$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();
    }
);

如果你必须打电话给$promise->wait()来提出请求,那么承诺有什么意义呢?这与以下方面有何不同:

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

if ($response

据我所知,唯一的好处是它是定义请求成功和失败回调的便捷方法。甚至关于发出多个请求的文档部分也有下面的代码,它似乎阻止和执行所有请求...也许在“同时”。这就是我应该期待的吗?

// Wait on all of the requests to complete.
$results = Promise\unwrap($promises);

答案 1

我在这里四肢着地,但从我所读到的...

虽然 PHP 不能执行异步处理,但您可以打开多个流并处理它们的输入而不会阻塞。因此,在具有单个连接的示例中,是的,没有任何意义/好处。

但是,假设您要加载 5 个资源。使用异步方法可以使这些资源基本上并行加载 - 而不是仅在加载第一个资源时才启动第二个资源。

Guzzle提供了处理用例的方法,例如“在它们全部正确加载之后......”或“在它们全部加载或失败之后...”。

因此,我认为在处理可能同时发生的多个请求时,它应该能够实现更快的处理速度。


答案 2

异步需要一些反向思维。

下面是一个可能出现的可能有用的场景:给定一个API(http://ipsum.org/),您需要(按id)将数据列表(按id)返回到您的路由(或脚本) - 如果您执行程序性操作,则必须遍历每个请求并等待它全部返回。

使用Guzzle Promise,您可以为响应“准备”,然后在它回来时 - 您可以处理它。这样做的好处是,当您“等待”所有响应返回时,延迟现在是CEIL(收到的所有响应中最慢的响应时间),而不是N个请求x T个请求时间,而是并行发送。

换句话说,您正在并行而不是串行发送请求,以便等待响应恢复,或者您可以先预先执行 curl 调用,然后进行设置以“在我等待返回时确定,让我准备响应”。

后一部分将需要一些重组,因为我们习惯于“去获取,等待,然后用答案回来,我们可以对响应进行操作”


推荐