如何在 Guzzle 中正确实现异步 HTTP 请求

千磊小哥_6158

千磊小哥_6158

2026-09-09

687人浏览

原创

如何在 Guzzle 中正确实现异步 HTTP 请求

本文详解 Guzzle 的异步请求机制,指出常见误区(如误以为 getAsync() 会自动触发执行),并提供基于 Promise 链、EachPromise 和并发控制的完整可运行方案。

本文详解 guzzle 的异步请求机制,指出常见误区(如误以为 `getasync()` 会自动触发执行),并提供基于 promise 链、`eachpromise` 和并发控制的完整可运行方案。

Guzzle 的异步请求本质是基于 PHP 的 Promise 模式(通过 GuzzleHttp\Promise 实现),它并非真正的“后台线程式”异步,而是非阻塞的 I/O 调度——所有异步操作必须显式触发执行(如调用 wait()promise()->wait()),否则请求根本不会发出。你代码中 dd("NOT EXECUTED") 总是先执行,正是因为 $promises 生成器仅定义了 Promise 对象,但未被消费或等待;而 EachPromise 构造后若不调用 ->promise()->wait(),其内部的 Promise 也不会启动。

✅ 正确做法:确保 Promise 被消费并等待完成

以下是修复后的完整示例(已优化逻辑、增强健壮性):

use GuzzleHttp\Client;
use GuzzleHttp\Promise\EachPromise;
use GuzzleHttp\Exception\RequestException;

$page = $request->page;
$limit = $request->limit;
$pageStart = $page * $limit;
$startDate = $request->start_date;
$endDate = $request->end_date;
$query = $request->search ?? '';
$user_token = Crypt::decryptString($company->persistent_user_token);
$overallRecords = [];

$client = new Client([
    'base_uri' => env('BADGEBOX_BASE_URL'),
    'timeout'  => 30, // 建议显式设置超时
]);

// Step 1: 创建 Promise 生成器(注意:yield 返回的是 Promise 对象)
$promises = function () use ($pageStart, $limit, $user_token, $client, $startDate, $endDate, $query) {
    for ($page = $pageStart; $page getAsync($url)->then(
            function ($response) use (&$overallRecords) {
                $body = (string) $response->getBody();
                $data = json_decode($body, true);
                if (is_array($data)) {
                    $overallRecords = array_merge($overallRecords, $data);
                }
                return $response; // 可选:便于链式调试
            },
            function (RequestException $e) {
                \Log::error('Async request failed', [
                    'url' => (string) $e->getRequest()->getUri(),
                    'message' => $e->getMessage()
                ]);
                // 可选择抛出异常或静默忽略
            }
        );
    }
};

// Step 2: 使用 EachPromise 并发执行(concurrency=10 表示最多 10 个并发)
$eachPromise = new EachPromise($promises(), [
    'concurrency' => 10,
    'fulfilled' => function ($value) {
        // 单个请求成功时的回调(可选)
    },
    'rejected' => function ($reason) {
        // 单个请求失败时的回调(已由 then 的第二个参数处理,此处可留空)
    }
]);

// ✅ 关键:必须调用 wait() 才真正发起所有请求并阻塞直到全部完成
$eachPromise->promise()->wait();

// 此时 $overallRecords 已填充完毕
dd('ALL DONE', $overallRecords);

⚠️ 注意事项与最佳实践

  • 不要依赖 dd()then() 中调试dd() 会终止脚本,导致后续 Promise 无法执行。改用 Log::info() 或断点调试。
  • URL 参数务必 urlencode():特别是 queryuser_token,避免特殊字符引发 400 错误。
  • 始终设置 timeout:防止某个请求无限挂起,拖垮整个批处理。
  • 错误处理不可省略getAsync()then() 第二个参数或 EachPromiserejected 回调必须处理网络异常、JSON 解析失败等场景。
  • 内存敏感场景慎用大并发concurrency=10 适合多数 API,但若单页数据量极大,建议降至 3–5 并配合分页逻辑优化。
  • 替代方案考虑:如需更高阶的异步能力(如协程),可结合 Swoole 或 Laravel Octane,但 Guzzle 本身仍需 Promise 驱动。

通过以上修正,你的异步请求将真正并发执行,"EXECUTED" 将按预期输出,且 dd("NOT EXECUTED") 会被替换为最终聚合的数据结果。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2023.09.01

9044

6

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

5501

5

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

2015

5

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

2023.10.23

3408

4

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

2023.10.23

4074

6

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.03

3191

9

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.09

4537

8

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.13

3542

8

sprintf函数用法详解
sprintf函数用法详解

sprintf函数的用法:1、格式化字符串;2、指定输出宽度和精度;3、返回值。更多关于sprintf函数用法详解的内容,大家可以阅读下面的文章。

2023.11.27

11582

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.1万人学习