最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何用 postMessage 与 onmessage 在主线程与线程间通信
时间:2026-08-06 14:51:49 编辑:袖梨 来源:一聚教程网
如何用 postMessage 与 onmessage 在主线程与线程间通信的重点在于把前置条件、操作顺序和容易误判的地方分清楚。
主线程与Web Worker通过postMessage和onmessage实现双向异步通信,支持结构化克隆数据及transferList零拷贝传输;Worker可用addEventListener避免监听器覆盖;MessageChannel可实现多端隔离通信。
主线程与 Web Worker 之间通过 postMessage 和 onmessage 实现双向通信,核心是“发送消息”和“监听消息”两个动作,且双方都需主动参与。
主线程向 Worker 发送消息
在主线程中创建 Worker 实例后,调用其 postMessage() 方法即可发送数据:
- 支持发送结构化克隆(如对象、数组、Date、Map、Set 等),但不能传函数、DOM 节点或带有循环引用的对象
- 可选第二个参数
transferList,用于零拷贝传输ArrayBuffer或MessagePort,提升大数组性能
const worker = new Worker('worker.js');worker.postMessage({ type: 'START', data: [1, 2, 3] });// 或传输 ArrayBuffer(原数组将被清空)const buffer = new ArrayBuffer(1024);worker.postMessage(buffer, [buffer]);
Worker 中接收并响应主线程消息
在 worker.js 中,通过全局的 onmessage 属性或 addEventListener('message', ...) 监听主线程发来的消息:
-
event.data是主线程发送的数据副本(结构化克隆) - Worker 可以直接调用
postMessage()回复主线程,同样支持transferList - 避免在 Worker 中修改
onmessage多次,否则会覆盖前一个监听器;推荐用addEventListener更安全
self.onmessage = function(e) { const { type, data } = e.data; if (type === 'START') { const result = data.map(x => x * 2); self.postMessage({ type: 'RESULT', data: result }); }};
主线程监听 Worker 的返回消息
主线程需为 Worker 实例设置 onmessage 或添加事件监听器来接收 Worker 的回复:
-
worker.onmessage是最常用方式,e.data即 Worker 发来的数据 - 若需处理多个 Worker 或更精细控制,可用
worker.addEventListener('message', ...) - 注意错误处理:监听
worker.onerror或使用try/catch包裹 Worker 内部逻辑
worker.onmessage = function(e) { console.log('Worker 返回:', e.data); // { type: 'RESULT', data: [2, 4, 6] }};<p>worker.onerror = function(e) {console.error('Worker 执行出错:', e.message);};
进阶:使用 MessageChannel 实现多端通信
当需要主线程与多个 Worker 之间隔离通信,或 Worker 之间直连,可借助 MessageChannel:
- 创建后得到两个
MessagePort对象,各自持有独立通道的一端 - 一端可传给 Worker:
worker.postMessage(..., [port]),Worker 收到后调用port.start()并监听port.onmessage - 这样避免所有消息都挤在默认
onmessage上,实现点对点、解耦通信
相关文章
- 鹅鸭杀超级金水铃模式怎么玩 08-07
- 牧场物语风之繁华集市生日日期怎么看 08-07
- 口袋新旅途如何捕捉颓颓鹰 08-07
- DNF狄瑞吉版本女漫游加点攻略 08-07
- 鹅鸭杀士兵怎么玩 08-07
- DNF狄瑞吉版本协战师加点攻略 08-07