在返回响应之前等待 Guzzle 异步请求



我有一个这样的控制器:

<?php
namespace AppHttpControllers;
use AppHelpersLogHelper;

class ExampleController {
public function test() {
$client = new GuzzleHttpClient();
LogHelper::logTo('s3_logs', 'starting requests');
$p1 = self::testRequest1($client);
$p2 = self::testRequest2($client);
$p3 = self::testRequest3($client);
return response()->json(['success' => true]);
}
private static function testRequest1($client) {
return $client->requestAsync('GET', 'http://www.zara.com/')
->then(function($response) {
LogHelper::logTo('s3_logs', 'resolved from zara.com');
}, function($e) {
LogHelper::logTo('s3_logs', 'rejected from zara.com');
});
}
private static function testRequest2($client) {
return $client->requestAsync('GET', 'http://www.google.com')
->then(function($response) {
LogHelper::logTo('s3_logs', 'resolved from google.com');
}, function($e) {
LogHelper::logTo('s3_logs', 'rejected from google.com');
});
}
private static function testRequest3($client) {
return $client->requestAsync('GET', 'http://httpbin.org/get')
->then(function($response) {
LogHelper::logTo('s3_logs', 'resolved from httpbin.org');
}, function($e) {
LogHelper::logTo('s3_logs', 'rejected from httpbin.org');
});
}
}
">

test"方法运行良好,并且完全正确地返回"成功"json,我已经进行了三重检查。

但是据我所知,这些异步请求根本没有运行。我的 LogHelper::logTo 函数(我敢肯定,它再次运行良好(只记录"启动请求",而不是任何其他内容。

我尝试过这个作为替代方案——等待承诺解决,但我认为 laravel 不喜欢这样,当我这样做时是错误的:

public function test() {
$client = new GuzzleHttpClient();
LogHelper::logTo('s3_logs', 'starting requests');
$p1 = self::testRequest1($client);
$p2 = self::testRequest2($client);
$p3 = self::testRequest3($client);
return $p1->then(function() {
return response()->json(['success' => true]);
});
}

此错误与"响应内容必须是实现 __toString(( 的字符串或对象">

在 Guzzle 承诺解决后,我如何返回我的回复?即使单独返回响应,为什么我的异步请求没有运行和解析?

多亏@PtrTron我找到了正确的答案:

首先,这奏效了:

$p1->wait();
$p2->wait();
$p3->wait();
return response()->json(['success' => true]);

它不仅有效,我还验证了请求的解析顺序也不正确,这意味着它绝对是异步的。

然后我做了这个工作,稍微好一点:

$results = GuzzleHttpPromiseall([$p1, $p2, $p3])->wait();
return response()->json(['success' => true]);

您也可以使用

$results = GuzzleHttpPromisesettle([$p1, $p2, $p3])->wait();

如果您没有捕获承诺拒绝,则可以通过包装 try\catch 来捕获来自all的错误,而来自settle的错误可以在 $results 数组中看到,其中该数组的每个成员都是一个关联数组,其属性state可以"拒绝"或"实现">

最新更新