用 Promise 封装 postMessage/onmessage 可结构化 Worker 通信:为每次请求生成唯一 ID,Map 存储 resolve/reject,响应时匹配触发;支持超时、async/await、错误捕获及 transferable 优化。

直接用 postMessage 和 onmessage 处理 Web Worker 通信容易混乱,尤其在并发多个任务时。异步编程的核心价值,就是把这种“发出去、等回来、再处理”的流程,变成可读、可链、可错的结构化操作。
用 Promise 封装单次通信
每个请求配一个唯一 ID,用 Promise 管理对应响应,避免 onmessage 全局监听带来的匹配难题:
- 主线程中创建
Map存储requestId → { resolve, reject } - 调用
sendWorkerMessage(worker, payload)时生成新 ID,返回new Promise - Worker 回传消息时带上该 ID,主线程查表触发对应
resolve或reject - 建议加超时控制(如 10 秒),防止无响应导致 Promise 悬停
配合 async/await 写线性逻辑
封装好 Promise 接口后,业务代码就能像写同步一样推进:
const result = await sendWorkerMessage(worker, { type: 'filter', data: bigArray })- 支持
try/catch统一捕获 Worker 错误或超时异常 - 多个 Worker 调用可自然串行或并行:
await Promise.all([task1(), task2()]) - 不再需要手动维护回调嵌套或事件监听器生命周期
注意数据可序列化与性能边界
异步只是让通信更可控,不改变底层限制:
- 传递对象必须能被结构化克隆:避开函数、DOM 节点、循环引用
- 大数组或图像数据优先用
transferable(如postMessage(data, [data.buffer]))减少拷贝开销 - 频繁通信场景下,避免每次新建 Promise + ID,可复用通道或改用
MessageChannel - Worker 内部也建议用
async/await处理 fetch、索引 DB 等异步操作,再统一 postMessage 返回
错误与生命周期要主动兜底
异步封装不能掩盖底层脆弱性,需额外加固:
- 主线程监听
worker.onerror,捕获脚本语法错误或未捕获异常 - Worker 自身监听
self.addEventListener('error')并主动上报,而非静默终止 - 任务完成及时调用
self.close();主线程必要时用worker.terminate()强制释放 - 避免因 Promise 未 reject 导致内存泄漏,Map 中已完成项要及时
delete



















