发送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
相关产品推荐
相关产品推荐

