Guzzle Http异步请求未执行问题排查求助
问题分析与修复方案
核心问题1:URL拼接错误导致请求失败
你创建Guzzle Client时已设置base_uri为env('BADGEBOX_BASE_URL'),但调用getAsync()时又传入了完整URL,导致最终请求的URL出现重复域名(比如https://xxx.comhttps://xxx.com/...),这种无效URL直接触发请求失败,Promise进入rejected状态。
修复方式:
去掉getAsync()中的完整域名,仅传递接口路径,同时用query参数数组传递查询参数(避免手动拼接的编码错误):
yield $client->getAsync("/server/api/v1/company/overall", [ 'query' => [ 'user_token' => urlencode($user_token), 'limit' => 1, 'page' => $page, 'start_date' => $startDate, 'end_date' => $endDate, 'query' => $query ] ])->then(function ($response) use (&$overallRecords) { // 回调逻辑 });
核心问题2:未处理Promise失败状态
你的EachPromise配置了空的rejected回调,请求失败时无任何提示,无法排查问题。
修复方式:
在rejected回调中添加错误输出或日志记录:
'rejected' => function ($reason) { dd('请求失败:', $reason->getMessage(), $reason->getResponse()?->getBody()->getContents()); // 或用日志记录:Log::error('BadgeBox API请求失败', ['reason' => $reason->getMessage()]); }
分页逻辑可能存在错误
当前$pageStart = $page * $limit的计算逻辑,若前端传入的$page从1开始,会直接跳过前$limit条数据对应的页码(比如page=1、limit=10时,会请求page=10到19的接口)。
修复方式:
若接口页码从1开始,修正分页起始计算:
$pageStart = ($page - 1) * $limit;
同时调整循环的起始和结束值,确保请求正确的页码范围:
for ($currentPage = $pageStart + 1; $currentPage <= $pageStart + $limit; $currentPage++) { // 使用$currentPage作为请求的page参数 }
额外问题:dd("EXECUTED")会终止脚本
dd()是Laravel的终止函数,一旦执行会直接停止脚本,导致后续Promise无法处理。建议替换为dump()或日志输出:
dump("EXECUTED"); // 或 Log::info("异步请求完成");
修复后的完整代码示例
$page = $request->page; $limit = $request->limit; // 修正分页起始页码(适配接口从1开始的页码规则) $pageStart = ($page - 1) * $limit; $startDate = $request->start_date; $endDate = $request->end_date; $query = $request->search ?? ""; $user_token = Crypt::decryptString($company->persistent_user_token); $overallRecords = []; $client = new \GuzzleHttp\Client([ 'base_uri' => env('BADGEBOX_BASE_URL') ]); $promises = (function () use ($pageStart, $user_token, $client, $limit, $startDate, $endDate, $query, &$overallRecords) { for ($currentPage = $pageStart + 1; $currentPage <= $pageStart + $limit; $currentPage++) { yield $client->getAsync("/server/api/v1/company/overall", [ 'query' => [ 'user_token' => urlencode($user_token), 'limit' => 1, 'page' => $currentPage, 'start_date' => $startDate, 'end_date' => $endDate, 'query' => $query ] ])->then(function ($response) use (&$overallRecords) { dump("EXECUTED"); $data = json_decode($response->getBody(), true); if (!empty($data)) { foreach ($data as $record) { $overallRecords[] = $record; } } }); } })(); $eachPromise = new \GuzzleHttp\Promise\EachPromise($promises, [ 'concurrency' => 10, 'fulfilled' => function () { // 可选:单个请求完成后的额外处理 }, 'rejected' => function ($reason) { dd('请求失败:', $reason->getMessage(), $reason->getResponse()?->getBody()->getContents()); } ]); $eachPromise->promise()->wait(); dd("所有异步请求完成", $overallRecords);
内容的提问来源于stack exchange,提问作者user3101803
相关产品推荐
相关产品推荐

