Worker.postMessage()
Worker 接口的 postMessage() 方法可以向 worker 发送消息。第一个参数是要发送到 worker 的数据。该数据可以是任何可以被结构化克隆算法处理的 JavaScript 对象。
Worker 的 postMessage() 方法委托给 MessagePort 的 postMessage() (en-US) 方法,该方法会在对应的用于接收 MessagePort 的事件循环中添加一个任务。
Worker 可以使用 DedicatedWorkerGlobalScope.postMessage (en-US) 方法将信息发送回生成它的线程。
语法
js
postMessage(message)
postMessage(message, transfer)
参数
message-
要传递给 worker 的对象;这将在传递给
DedicatedWorkerGlobalScope.message_event(en-US) 事件的data字段中。这可以是任何值或可以通过结构化克隆算法处理的 JavaScript 对象(可以包含循环引用)。如果未提供
message参数,则解析器将抛出SyntaxError。如果要传递给 worker 的数据不重要,可以显式传递null或undefined。 transfer可选-
一个可选的、会被转移所有权的可转移对象数组。如果一个对象的所有权被转移,它将在发送它的上下文中变为不可用(中止),而仅在接收方的 worker 中可用。
像
ArrayBuffer、MessagePort或ImageBitmap类的实例才是可转移对象,才能够被转移。不能将null作为transfer的值。
返回值
无 (undefined)。
示例
下面的代码片段展示了使用 Worker() 构造函数创建一个 Worker 对象。当两个表单输入框(first 和 second)的值发生改变时,change 事件将调用 postMessage(),以将这两个输入框的值发送给当前的 worker。
js
const myWorker = new Worker("worker.js");
first.onchange = () => {
myWorker.postMessage([first.value, second.value]);
console.log("消息已传递给 worker");
};
second.onchange = () => {
myWorker.postMessage([first.value, second.value]);
console.log("消息已传递给 worker");
};
有关完整的示例,请参阅我们的简单 worker 示例和(运行示例)。
备注: postMessage() 一次只能发送一个对象。如上所示,如果你想传递多个值,可以使用数组。
转移示例
这个最小化的例子中,main 中创建了一个 ArrayBuffer,并将其发送给 myWorker,然后让 myWorker 将其转移回 main,并在每个步骤中记录大小。
main.js 代码
js
// 创建 worker
const myWorker = new Worker("myWorker.js");
// 监听 myWorker 将缓冲区传回 main
myWorker.addEventListener("message", function handleMessageFromWorker(msg) {
console.log("message from worker received in main:", msg);
const bufTransferredBackFromWorker = msg.data;
console.log(
"buf.byteLength in main AFTER transfer back from worker:",
bufTransferredBackFromWorker.byteLength
);
});
// 创建 buffer
const myBuf = new ArrayBuffer(8);
console.log(
"buf.byteLength in main BEFORE transfer to worker:",
myBuf.byteLength
);
// 发送 myBuf 给 myWorker 并转移底层 ArrayBuffer
myWorker.postMessage(myBuf, [myBuf]);
console.log(
"buf.byteLength in main AFTER transfer to worker:",
myBuf.byteLength
);
myWorker.js 代码
js
// 监听 main 并将缓冲区转移到 myWorker
self.onmessage = function handleMessageFromMain(msg) {
console.log("message from main received in worker:", msg);
const bufTransferredFromMain = msg.data;
console.log(
"buf.byteLength in worker BEFORE transfer back to main:",
bufTransferredFromMain.byteLength
);
// 将 buf 发送回 main 并转移底层 ArrayBuffer
self.postMessage(bufTransferredFromMain, [bufTransferredFromMain]);
console.log(
"buf.byteLength in worker AFTER transfer back to main:",
bufTransferredFromMain.byteLength
);
};
输出日志
bash
buf.byteLength in main BEFORE transfer to worker: 8 main.js:19
buf.byteLength in main AFTER transfer to worker: 0 main.js:27
message from main received in worker: MessageEvent { ... } myWorker.js:3
buf.byteLength in worker BEFORE transfer back to main: 8 myWorker.js:7
buf.byteLength in worker AFTER transfer back to main: 0 myWorker.js:15
message from worker received in main: MessageEvent { ... } main.js:6
buf.byteLength in main AFTER transfer back from worker: 8 main.js:10
ArrayBuffer 在传输后, 其 byteLength 将变为 0。要查看此 Firefox 演示插件的完整可运行示例,请参阅此处:GitHub :: ChromeWorker - demo-transfer-arraybuffer
规范
| Specification |
|---|
| HTML Standard # dom-worker-postmessage-dev |
浏览器兼容性
BCD tables only load in the browser
参见
- 它属于
Worker接口。