全书目录

第二十七篇:Laravel 完全指南 —— 工匠城区宇宙

第八章:Event 和 Queue —— 城区广播与后台传送带

1 分钟 198 字 第 485 / 962 个阅读单元

这是 Laravel 非常“城区化”的另一部分。

很多系统在同步请求里做太多事:

  • 创建订单
  • 发短信
  • 发邮件
  • 记审计日志
  • 通知仓库
  • 生成发票
  • 推送到 CRM

结果就是前台工头一边接单,一边自己冲去后场干体力活。

Laravel 的思路更像成熟城区:

text
Event = 某件事发生了,广播出去
Queue = 这件慢活别堵前台,送到后场传送带

最关键的一刀是:

事件不是任务,任务也不是事件。

text
OrderCreated
= “订单已创建”这个事实发生了

SendInvoiceJob
= “请去生成发票”这个待执行动作

一个简单事件:

php
use App\Models\Order;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class OrderCreated
{
    use Dispatchable, SerializesModels;

    public function __construct(
        public Order $order,
    ) {}
}

一个监听器可以选择进入队列:

php
<?php

namespace App\Listeners;

use App\Events\OrderCreated;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\Queueable;
use Illuminate\Support\Facades\Log;

class PrepareWorkshopMaterials implements ShouldQueue
{
    use InteractsWithQueue, Queueable;

    public function handle(OrderCreated $event): void
    {
        Log::info('准备订单物料', [
            'order_id' => $event->order->id,
            'product' => $event->order->product,
            'quantity' => $event->order->quantity,
        ]);
    }
}

关系图如下:

text
Controller / Service
      |
      v
Event::dispatch(new OrderCreated($order))
      |
      v
Listener
      |
      +--> 同步执行
      |
      +--> 或实现 ShouldQueue
              |
              v
            Queue
              |
              v
         Queue Worker

这套模型特别像现实工坊:

text
前台先确认“订单已成立”
然后广播给后场
后场各工位再异步做自己的活

这就是解耦。