Worker: postMessage() 方法

Baseline 已广泛支持

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2015 年 7 月⁩以来,各浏览器均已提供此特性。

注意:此功能在 Web Workers 中可用,但 Service Workers 除外。

Worker 接口的 postMessage() 方法用于向工作线程发送消息。第一个参数是要发送给工作线程的数据。数据可以是任何能被 结构化克隆算法 处理的 JavaScript 对象。

WorkerpostMessage() 方法会委托给 MessagePortpostMessage() 方法,该方法会在事件循环中添加一个任务,对应于接收的 MessagePort

Worker 可以使用 DedicatedWorkerGlobalScope.postMessage 方法将信息回传给创建它的线程。

语法

js
postMessage(message)
postMessage(message, transfer)
postMessage(message, options)

参数

message

要传递给工作线程的对象;这将出现在发送给 message 事件的 data 字段中。这可以是任何值或 JavaScript 对象,只要它们能被 结构化克隆 算法处理,包括循环引用。

message 参数是必需的。如果要传递给工作线程的数据不重要,必须显式传递 nullundefined

transfer 可选

一个可选的可传输对象数组,用于转移所有权。这些对象的所有权将转移到目标方,并且它们在发送方不再可用。这些可传输对象应该附加到消息中;否则它们将被移动,但在接收端实际上无法访问。

options 可选

一个包含以下属性的可选对象

transfer 可选

transfer 参数具有相同的含义。

返回值

无(undefined)。

示例

以下代码片段展示了如何使用 Worker() 构造函数创建一个 Worker 对象。当两个表单输入(firstsecond)中的任何一个的值发生变化时,change 事件会调用 postMessage() 将两个输入的值发送到当前工作线程。

js
const myWorker = new Worker("worker.js");

[first, second].forEach((input) => {
  input.onchange = () => {
    myWorker.postMessage([first.value, second.value]);
    console.log("Message posted to worker");
  };
});

完整示例,请参阅我们的 简单工作线程示例运行示例)。

注意: postMessage() 一次只能发送一个对象。如上所示,如果您想传递多个值,可以发送一个数组。

传输示例

这个最小示例展示了 main 创建一个 ArrayBuffer 并将其传输给 myWorker,然后 myWorker 将其传回 main,并在每一步记录大小。

main.js 代码

js
// create worker
const myWorker = new Worker("myWorker.js");

// listen for myWorker to transfer the buffer back to main
myWorker.addEventListener("message", (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,
  );
});

// create the buffer
const myBuf = new ArrayBuffer(8);

console.log(
  "buf.byteLength in main BEFORE transfer to worker:",
  myBuf.byteLength,
);

// send myBuf to myWorker and transfer the underlying ArrayBuffer
myWorker.postMessage(myBuf, [myBuf]);

console.log(
  "buf.byteLength in main AFTER transfer to worker:",
  myBuf.byteLength,
);

myWorker.js 代码

js
// listen for main to transfer the buffer to myWorker
self.onmessage = (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,
  );

  // send buf back to main and transfer the underlying 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。有关更复杂的 ArrayBuffer 传输的完整工作示例,请参阅此 Firefox 演示插件:GitHub :: ChromeWorker - demo-transfer-arraybuffer

规范

规范
HTML
# dom-worker-postmessage-dev

浏览器兼容性

另见

  • 它所属的 Worker 接口。