如何使用Laravel Job替代do while实现异步API结果的等待处理?
基于Laravel Job实现第三方服务异步轮询方案
无需搭配额外cron任务持续调用队列,使用Laravel自带的队列延迟派发+任务自调度能力即可实现需求,同时能解决原同步轮询方案的请求阻塞、资源占用高的问题。
实现逻辑说明
原同步轮询方案会一直占用FPM进程等待,极端情况下30分钟的处理时长会直接导致HTTP请求超时,根本无法同步返回结果。调整为异步方案后:
- 接口层收到请求后先调用第三方服务生成listId,直接将轮询任务派发到队列,立刻给用户返回异步提示
- 轮询任务自行检查第三方服务状态,未完成则延迟10秒后重新派发自己,完成后执行数据入库和后续通知逻辑
- 只需常驻队列进程即可,Laravel队列自带延迟任务调度能力,无需额外cron触发
具体实现步骤
1. 创建轮询任务类
执行命令生成Job类:php artisan make:job PollActivityListJob
编写Job逻辑:
<?php namespace App\Jobs; use App\Models\ActivityList; use App\Services\ListService; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class PollActivityListJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; // 配置最大重试次数:按30分钟、10秒轮询一次计算,配置200次足够覆盖极端场景 public $tries = 200; protected string $listId; public function __construct(string $listId) { $this->listId = $listId; } public function handle(ListService $listService) { $checkResult = $listService->checkList($this->listId); // 状态为处理中则延迟10秒重新执行当前任务 if ($checkResult->getStatus() === 'pending') { self::dispatch($this->listId)->delay(now()->addSeconds(10)); return; } // 处理完成则拉取数据入库 if ($checkResult->getStatus() === 'complete') { $data = $listService->getList($this->listId)->getData(); $activityList = ActivityList::create($data); // 此处补充业务逻辑:比如触发推送通知、websocket推送给前端、更新用户消息等 // event(new ActivityListGenerated($activityList)); } // 可自行补充第三方返回失败状态的异常处理逻辑 } }
2. 调整业务接口代码
$listService = new ListService(); $res = $listService->createList('USER_ACTIVITY_LIST'); $listId = $res->getListId(); // 直接派发轮询任务到队列 \App\Jobs\PollActivityListJob::dispatch($listId); // 返回异步响应给前端,可携带listId用于前端后续查询结果 return response()->json([ 'code' => 0, 'msg' => '数据正在生成,完成后将自动通知', 'list_id' => $listId ]);
3. 队列配置
- 开发环境执行
php artisan queue:work启动队列进程即可 - 生产环境使用Supervisor托管队列进程,保证进程常驻不中断,不需要额外配置cron任务
前端获取结果方案
如果需要用户能第一时间看到结果,可选择两种实现:
- 前端根据返回的listId,每隔几秒轮询后端本地接口查询对应ActivityList记录是否生成
- 服务端任务完成后通过websocket主动推送结果给对应用户
内容的提问来源于stack exchange,提问作者bariskau
相关产品推荐
相关产品推荐

