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

发送Laravel任务时,如何实现pending与success状态的正确展示?

实现方案

1. 核心思路

给每条待发送消息分配一个临时唯一ID,前端用这个ID标记等待列表中的条目;后端在Job执行完成并广播事件时,将该临时ID一并返回给前端,前端收到事件后再删除对应等待条目,以此确保pending状态持续到Job执行完成。

2. 前端调整

  • 发送消息前,生成临时ID(如UUID或时间戳+随机数),将消息内容、临时ID加入waitings列表,标记为pending状态
  • 发送请求时,除message参数外,额外携带temp_id字段
  • 取消请求成功后删除等待条目的逻辑,改为监听MessageSent事件,收到事件后通过返回的temp_id匹配删除对应条目,并将正式消息加入列表

示例前端代码:

// 生成临时ID(假设使用uuid库)
const tempId = uuid();
// 添加至等待列表
waitings.value.push({
    id: tempId,
    content: messageContent,
    status: 'pending'
});

// 发送请求
axios.post(`/chats/${chatId}/messages`, {
    message: messageContent,
    temp_id: tempId
}).catch(err => {
    // 请求失败时标记消息状态为失败
    const targetIndex = waitings.value.findIndex(item => item.id === tempId);
    if (targetIndex !== -1) {
        waitings.value[targetIndex].status = 'failed';
    }
});

// 监听广播事件
Echo.channel(`chat.${chatId}`)
    .listen('MessageSent', (eventData) => {
        // 删除对应等待条目
        const targetIndex = waitings.value.findIndex(item => item.id === eventData.temp_id);
        if (targetIndex !== -1) {
            waitings.value.splice(targetIndex, 1);
        }
        // 添加正式消息到列表
        messages.value.push(eventData.message);
    });

3. 后端调整

(1)更新Store方法,接收并传递临时ID

public function store(MessageRequest $request, $chatId) {
    $tempId = $request->temp_id;
    // 将临时ID传入Job
    MessageJob::dispatch($chatId, auth()->user(), $request->message, $tempId);
    return response()->json(['temp_id' => $tempId], 200);
}

同时在MessageRequest中添加temp_id的验证规则:

public function rules() {
    return [
        'message' => 'required|string',
        'temp_id' => 'required|string'
    ];
}

(2)修改Job类,存储临时ID

private $chatId;
private $userId;
private $message;
private $tempId;

public function __construct($chatId, User $user, string $message, string $tempId) {
    $this->chatId = $chatId;
    $this->userId = $user->id;
    $this->message = $message;
    $this->tempId = $tempId;
}

(3)更新广播事件,携带临时ID

首先修改MessageSent事件类:

private $message;
private $tempId;

public function __construct(Message $message, string $tempId) {
    $this->message = $message;
    $this->tempId = $tempId;
}

// 定义广播携带的数据
public function broadcastWith() {
    return [
        'message' => $this->message->toArray(),
        'temp_id' => $this->tempId
    ];
}

然后在Job的handle方法中广播时传入临时ID:

public function handle(): void {
    $message = Message::create([
        'chat_id' => $this->chatId,
        'user_id' => $this->userId,
        'message' => $this->message,
    ]);
    // 广播事件时携带临时ID
    broadcast(new MessageSent($message, $this->tempId));
}

内容的提问来源于stack exchange,提问作者fjduqrllhdnolvgrcc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 09:37:30