postMessage传参必须是可序列化的值,如字符串、数字、数组、普通对象等;不可传函数、DOM节点、undefined、Symbol或循环引用,否则静默失败。

postMessage 传参必须是可序列化的值
Web Worker 的 postMessage 不支持传递函数、DOM 节点、undefined、Symbol 或循环引用对象。一旦传入,主线程或 Worker 会静默失败(不报错但接收不到),Worker 中的 onmessage 根本不会触发。
常见踩坑:直接传 {data: document.body} 或 {callback: () => {}} —— 这类值会被自动过滤掉,且无提示。
- ✅ 安全传参类型:字符串、数字、布尔、
null、数组、普通对象(仅含上述类型)、Date、RegExp(部分浏览器支持)、ArrayBuffer和TypedArray - ✅ 大数据推荐用
transferable:如postMessage(data, [arrayBuffer]),可零拷贝移交内存,避免主线程卡顿 - ⚠️ 注意
JSON.stringify兜底不万能:它会丢掉undefined、函数、Date的原始类型信息(变成字符串)
主线程调用 postMessage 的正确写法
必须确保 Worker 实例已创建且 onmessage 已绑定,否则消息会丢失(不是队列缓存,而是直接丢弃)。
典型错误:先 worker.postMessage(),再 worker.onmessage = ... —— 消息发出去时监听器还没挂上,收不到。
立即学习“前端免费学习笔记(深入)”;
- ✅ 推荐写法:创建 Worker 后立即绑定
onmessage,再发消息 - ✅ 可传对象字面量,无需 JSON 序列化:
worker.postMessage({type: 'FETCH', url: '/api/data'}) - ✅ 如需传二进制数据,优先用
ArrayBuffer+transfer:worker.postMessage(buffer, [buffer]) - ❌ 避免在
worker.terminate()后还调用postMessage,会抛InvalidStateError
Worker 线程里接收和响应消息
Worker 内部不能用 document 或 window,所有通信靠 self.onmessage 和 self.postMessage。注意:全局上下文是 self,不是 window。
- ✅ 接收消息必须监听
self.onmessage,不是window.onmessage(后者无效) - ✅ 响应主线程可用
self.postMessage({result: data}),结构随意,只要可序列化 - ⚠️ 若主线程用
worker.addEventListener('message', ...),Worker 仍用self.postMessage发送,两者兼容 - ⚠️ 不要漏掉
event.data解构:常见错误是直接用event当数据,实际数据在event.data里
调试时看不到 postMessage 数据?检查这三点
Chrome/Firefox 的 DevTools Workers 面板默认不显示 postMessage 内容,容易误判“没发出去”或“没收到”。
- ✅ 在主线程加
console.log('sending:', msg),在 Worker 的onmessage里加console.log('received:', event.data) - ✅ 检查 Worker 脚本路径是否 404:控制台报
Failed to load worker script会导致postMessage无声失效 - ✅ 查看 Network 面板确认 Worker JS 是否加载成功(状态码 200),MIME 类型必须是
text/javascript
跨域 Worker 脚本、内联脚本(Blob URL)或 Service Worker 干扰都可能让 postMessage 表现异常——这些边界情况比想象中更常出现。



















