You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 21:15:03