MessageChannel API
MessageChannel 为通信管道对象,使用 MessageChannel 构造函数将返回一个 MessageChannel 对象,返回的对象中包含两个 MessagePort 对象,可以实现双端通信。
MessageChannel的onmessage回调属于宏任务。
// 创建 MessageChannel 新实例对象
var channel = new MessageChannel();
// MessageChannel实例默认具有port1和port2两个对象属性
var port1 = channel.port1;
var port2 = channel.port2;
// MessageChannel实例onmessage事件可以实现监听并绑定回调函数
port1.onmessage = function(event) {
console.log("port1收到来自port2的数据:" + event.data);
}
port2.onmessage = function(event) {
console.log("port2收到来自port1的数据:" + event.data);
}
// MessageChannel实例postMessage方法可以触发onmessage事件
port1.postMessage("发送给port2");
port2.postMessage("发送给port1");
MessageChannel 结合 Web Worker 可以实现多线程通信:
// main.js
let worker1 = new Worker('./worker1.js');
let worker2 = new Worker('./worker2.js');
let ms = new MessageChannel();
// 把 port1 分配给 worker1
worker1.postMessage({ name: 'port', port: ms.port1 }, [ms.port1]);
// 把 port2 分配给 worker2
worker2.postMessage({ name: 'port', port: ms.port2}, [ms.port2]);
以上代码把消息通道的 port1 和 port2 分别分配给了 worker1和 worker2,即用消息通道将两个 worker 给连接起来。
关于 postMessage
Web Worker 的 postMessage 方法 可接收两个参数:
message: 消息内容,可以是任意基础数据类型或ArrayBuffer、MessageChannel、ImageBitmap等实例对象
transferList: 可选,包含被传输对象的数组,数组中的对象的所有权会转移给当前调用postMessage 方法 的Web Worker
// worker1.js
self.onmessage = function(e) {
if (e.data.name === 'port') {
const port = e.data.port;
port.postMessage("Hi! I'm worker1");
}
}
// worker2.js
self.onmessage = function(e) {
if (e.data.name === 'port') {
const port = e.data.port;
port.onmessage = function(event) {
console.log(event.data);
}
}
}
代码运行时,worker1 中通过 port1 发送消息,然后 worker2 就能从 port2 中接收到消息。