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 介面。