Laravel 11.x如何封装子流程并链式调用队列任务?
实现子流程函数的可组合大任务链(Laravel 11 + 亚马逊SP-API)
当然可以实现这种子流程的组合复用,不用直接编写冗长的大Job链或额外创建父Job。下面是几种贴合Laravel 11特性的可行方案:
方案1:让子流程函数返回Job链实例,直接拼接组合
核心思路是改造现有子流程函数,不再直接分发Job链,而是返回Illuminate\Bus\Chain实例,这样就能在大流程中把多个子链的Job数组展开合并,形成完整的大任务链。
改造子流程函数
use Illuminate\Bus\Chain; // 子流程:创建入库计划(返回Job链实例,而非直接分发) function createInboundPlan(array $payload): Chain { return new Chain([ new CreateInboundPlanJob($payload), new PollOperationStatusJob('create_inbound_plan'), // 其他关联Job... ]); } // 子流程:生成配送标签 function generateShippingLabel(array $planData): Chain { return new Chain([ new GenerateLabelJob($planData), new PollOperationStatusJob('generate_label'), new DownloadLabelJob(), // 其他关联Job... ]); }
组合成大任务链
use Illuminate\Bus\Chain; // 初始化参数 $initialPayload = ['seller_id' => 'XXX', 'sku_list' => [...]]; // 拼接子流程的Job链,按顺序执行 $fullWorkflow = new Chain([ // 展开第一个子流程的所有Job ...createInboundPlan($initialPayload)->jobs, // 展开第二个子流程的所有Job(若需要前一步结果,可从缓存/DB读取) ...generateShippingLabel($planResult)->jobs, // 继续添加其他子流程的Job链... ]); // 分发完整的大任务链 dispatch($fullWorkflow);
优点:子流程的复用性完全保留,大流程的结构清晰,所有Job按串行顺序执行。
注意:若子流程间需要传递数据,可在Job的handle方法中将结果存入缓存/数据库,后续Job从对应位置读取即可。
方案2:用闭包Job包装子流程调用,实现依赖触发
如果子流程之间存在严格的先后依赖(必须等前一个子流程完全执行完再启动下一个),可以用闭包Job作为链的节点,内部分发子流程的Job链,并通过then方法触发后续流程。
use Illuminate\Support\Facades\Bus; // 大流程入口 dispatch(function () use ($initialPayload) { // 执行第一个子流程,完成后触发第二个 Bus::chain(createInboundPlan($initialPayload)->jobs) ->then(function () { // 从缓存/DB获取前一步的结果 $planResult = cache()->get('latest_inbound_plan'); // 执行第二个子流程 Bus::chain(generateShippingLabel($planResult)->jobs)->dispatch(); }) ->dispatch(); });
优点:能精确控制子流程的触发时机,适合有强依赖的复杂场景。
方案3:利用Laravel Pipeline实现流程编排
如果子流程之间需要传递上下文数据,可以用Pipeline管道来编排,每个管道步骤对应一个子流程的执行:
use Illuminate\Pipeline\Pipeline; // 初始化上下文数据 $context = ['initial_payload' => $initialPayload]; // 编排流程 $finalResult = app(Pipeline::class) ->send($context) ->through([ // 第一个子流程步骤 function ($context, $next) { // 执行子流程并获取结果 $planResult = Bus::chain(createInboundPlan($context['initial_payload'])->jobs)->dispatchSync(); $context['plan_result'] = $planResult; return $next($context); }, // 第二个子流程步骤 function ($context, $next) { $labelResult = Bus::chain(generateShippingLabel($context['plan_result'])->jobs)->dispatchSync(); $context['label_result'] = $labelResult; return $next($context); }, // 更多子流程步骤... ]) ->thenReturn();
优点:上下文数据传递直观,适合需要逐步加工数据的流程。
内容的提问来源于stack exchange,提问作者MaxWeb
相关产品推荐
相关产品推荐

