7.4 KiB
7.4 KiB
TaskId 丢失问题 - 调试指南
问题症状
- 打开编辑窗口后,taskId 为空或 undefined
- 控制台显示 "5秒内未收到数据,显示空界面"
- 编辑窗口的表单数据为空
最新修复方案(2025-10-14)
核心问题:窗口通信时序问题
- 问题:父窗口创建子窗口后才开始监听 ready 事件,导致错过子窗口的就绪通知
- 解决:父窗口在创建子窗口之前就开始监听 ready 事件
通信流程
父窗口 子窗口
| |
|-- 1. 开始监听 ready 事件 |
| (BEFORE creating window) |
| |
|-- 2. 创建窗口 ------------------> |
| |
| |-- 3. 窗口创建 (tauri://created)
| |
| |-- 4. Vue 组件 mounted
| |
| |-- 5. 设置事件监听器
| |
| |-- 6. 发送 ready 通知
| | emit('xxx-ready')
| |
|<-- 7. 收到 ready 通知 -------------|
| |
|-- 8. 发送初始化数据 -------------> |
| emit('init-task-edit-xxx') |
| |
| |<-- 9. 收到数据
| |
| |-- 10. 填充表单
| |
| |-- 11. 显示界面
备用超时机制
如果 2 秒内没收到 ready 通知(可能是通信失败),父窗口会直接发送数据:
setTimeout(async () => {
if (!readySent) {
console.log('⏰ 超时备用发送机制触发')
readySent = true
await sendInitData()
}
}, 2000)
调试步骤
1. 打开浏览器控制台
在应用中打开开发者工具(F12 或 Ctrl+Shift+I)
2. 清空控制台
点击控制台左上角的清空按钮(🚫)
3. 触发编辑操作
点击列表中某一行的"编辑"按钮
4. 观察日志输出
正常流程应该看到的日志:
父窗口(AI Index):
============ AI Index 创建编辑窗口 ============
创建的窗口标签 (windowLabel): task-edit-ai-1728912345678
将要发送的事件名 (eventName): init-task-edit-task-edit-ai-1728912345678
等待就绪事件名 (readyEventName): task-edit-ai-1728912345678-ready
传递的 taskData: {taskId: "123", taskName: "测试任务", ...}
taskData.taskId: 123
[task-edit-ai-1728912345678] 🎧 开始监听就绪事件: task-edit-ai-1728912345678-ready
[task-edit-ai-1728912345678] ✅ 窗口已创建
[task-edit-ai-1728912345678] 📢 收到子窗口就绪通知: {windowLabel: "task-edit-ai-1728912345678", ...}
[task-edit-ai-1728912345678] 📤 发送事件: init-task-edit-task-edit-ai-1728912345678
[task-edit-ai-1728912345678] 📦 payload.data.taskId: 123
[task-edit-ai-1728912345678] ✅ 事件发送成功!
子窗口(Task Edit Window):
============ AI Task Edit Window onMounted ============
当前窗口标签 (windowLabel): task-edit-ai-1728912345678
初始 form 数据: {taskId: "", ...}
将要监听的事件名: init-task-edit-task-edit-ai-1728912345678
[task-edit-ai-1728912345678] ai - ✅ 事件监听器已设置成功
[task-edit-ai-1728912345678] ai - 📢 已发送就绪通知: task-edit-ai-1728912345678-ready
[task-edit-ai-1728912345678] ai - ✅ 收到事件!event.payload: {type: "edit", data: {...}}
[task-edit-ai-1728912345678] ai - 接收到的数据: {taskId: "123", ...}
[task-edit-ai-1728912345678] ai - data.taskId: 123
[task-edit-ai-1728912345678] ai - assignFields 调用后 form: {taskId: "123", ...}
[task-edit-ai-1728912345678] ai - 赋值后 form.taskId: 123
[task-edit-ai-1728912345678] ai - incomingId: 123
[task-edit-ai-1728912345678] ai - resolvedId: 123
[task-edit-ai-1728912345678] ai - 已保存到 localStorage, taskId: 123
[task-edit-ai-1728912345678] ai - nextTick 后 form.taskId: 123
5. 常见问题诊断
问题 A:子窗口超时
[task-edit-ai-xxx] ai - ⚠️ 5秒内未收到数据,显示空界面
可能原因:
- 窗口标签不匹配
- 事件名称拼写错误
- 父窗口发送数据失败
检查:
- 确认父窗口和子窗口的 windowLabel 是否一致
- 确认事件名称是否正确(
init-task-edit-${windowLabel})
问题 B:父窗口超时发送
[task-edit-ai-xxx] ⏰ 超时备用发送机制触发
可能原因:
- 子窗口 ready 事件发送失败
- 父窗口监听器设置失败
- 子窗口加载太慢
检查:
- 查看子窗口是否发送了 ready 通知
- 查看网络是否正常(子窗口资源加载)
问题 C:taskId 为空字符串
[task-edit-ai-xxx] ai - data.taskId: undefined
[task-edit-ai-xxx] ai - incomingId: undefined
可能原因:
- 父窗口传递的数据本身就没有 taskId
- 字段名不匹配(可能是 taskid 或 id)
检查:
- 查看父窗口日志中的
payload.data.taskId - 查看父窗口日志中的
taskData
问题 D:重复发送数据
[task-edit-ai-xxx] ⚠️ 已经发送过数据,忽略重复通知
原因:
- 正常现象,防止重复发送的保护机制生效
检查 localStorage
打开浏览器控制台,输入:
// 查看当前存储的 taskId
localStorage.getItem('taskId')
// 清空 taskId
localStorage.removeItem('taskId')
检查事件监听器
在子窗口控制台输入:
// 查看当前窗口标签
await window.__TAURI__.window.getCurrent().label
// 手动发送就绪通知测试
await window.__TAURI__.event.emit('task-edit-ai-xxx-ready', { test: true })
修复建议
如果问题仍然存在
-
增加延迟:将超时时间从 2 秒增加到 3 秒
}, 3000) // 从 2000 改为 3000 -
直接发送(临时方案):在
tauri://created事件中直接发送数据webview.once('tauri://created', async () => { await new Promise((resolve) => setTimeout(resolve, 1000)) await sendInitData() }) -
使用全局事件总线:不依赖窗口标签,使用固定的事件名
// 使用固定的事件名 + taskId const eventName = `init-task-edit-${taskData.taskId}`
测试清单
- 从列表打开编辑窗口,taskId 正确显示
- 关闭窗口后重新打开,taskId 正确显示
- 网络慢时打开,超时机制正常工作
- 快速连续打开多个编辑窗口,互不干扰
- 编辑窗口刷新后,taskId 从 localStorage 恢复
- 关闭窗口后,localStorage 正确清理
性能优化建议
- 缓存窗口:不要每次都创建新窗口,复用已有窗口
- 预加载:提前创建隐藏窗口,需要时直接显示
- 批量操作:如果需要打开多个窗口,使用队列机制
联系与反馈
如果问题仍未解决,请收集以下信息:
- 完整的控制台日志(父窗口 + 子窗口)
- localStorage 内容快照
- 网络请求记录(Network 面板)
- Tauri 版本号
- 操作系统版本