port.postMessage(value[, transferList])
| 版本 | 變化 | 
|---|---|
| v15.6.0 | 將   | 
| v15.0.0 | 將   | 
| v15.14.0、v14.18.0 | 將'BlockList' 添加到可克隆類型列表中。  | 
| v15.9.0、v14.18.0 | 將 'Histogram' 類型添加到可克隆類型列表中。  | 
| v14.5.0、v12.19.0 | 將   | 
| v14.5.0、v12.19.0 | 將  | 
| v10.5.0 | 添加於:v10.5.0  | 
參數
value<any>transferList<Object[]>
將 JavaScript 值發送到此通道的接收端。 value 以與 HTML structured clone algorithm 兼容的方式傳輸。
特別是,與JSON 的顯著差異是:
value可能包含循環引用。value可能包含內置 JS 類型的實例,例如RegExps、BigInts、Maps、Sets 等。value可能包含類型化數組,兩者都使用ArrayBuffers 和SharedArrayBuffers。value可能包含實例。WebAssembly.Modulevalue不得包含除以下內容之外的本機(C++ 支持)對象:- <CryptoKey> 秒,
 - <FileHandle> 秒,
 - <Histogram> 秒,
 - <KeyObject> 秒,
 - <MessagePort> 秒,
 - <net.BlockList> 秒,
 - <net.SocketAddress> es,
 - <X509Certificate> 秒。
 
const { MessageChannel } = require('node:worker_threads');
const { port1, port2 } = new MessageChannel();
port1.on('message', (message) => console.log(message));
const circularData = {};
circularData.foo = circularData;
// Prints: { foo: [Circular] }
port2.postMessage(circularData);
transferList 可能是   、 ArrayBuffer   和 MessagePort   對象的列表。傳輸後,它們在通道的發送端不再可用(即使它們不包含在 FileHandle value 中)。與 child processes 不同,目前不支持傳輸網絡套接字等句柄。
如果 value 包含   實例,則可以從任一線程訪問這些實例。它們不能在 SharedArrayBuffer transferList 中列出。
value 可能仍包含不在 transferList 中的 ArrayBuffer 實例;在這種情況下,底層內存被複製而不是移動。
const { MessageChannel } = require('node:worker_threads');
const { port1, port2 } = new MessageChannel();
port1.on('message', (message) => console.log(message));
const uint8Array = new Uint8Array([ 1, 2, 3, 4 ]);
// This posts a copy of `uint8Array`:
port2.postMessage(uint8Array);
// This does not copy data, but renders `uint8Array` unusable:
port2.postMessage(uint8Array, [ uint8Array.buffer ]);
// The memory for the `sharedUint8Array` is accessible from both the
// original and the copy received by `.on('message')`:
const sharedUint8Array = new Uint8Array(new SharedArrayBuffer(4));
port2.postMessage(sharedUint8Array);
// This transfers a freshly created message port to the receiver.
// This can be used, for example, to create communication channels between
// multiple `Worker` threads that are children of the same parent thread.
const otherChannel = new MessageChannel();
port2.postMessage({ port: otherChannel.port1 }, [ otherChannel.port1 ]);
消息對象立即克隆,發布後可以修改,沒有副作用。
有關此 API 背後的序列化和反序列化機製的更多信息,請參閱 node:v8 模塊的序列化 API。
傳輸TypedArrays 和緩衝區時的注意事項#
所有 TypedArray 和 Buffer 實例都是底層 ArrayBuffer 的視圖。也就是說,實際存儲原始數據的是ArrayBuffer,而TypedArray 和Buffer 對象提供了一種查看和操作數據的方式。在同一個 ArrayBuffer 實例上創建多個視圖是可能的並且很常見。使用傳輸列表傳輸ArrayBuffer 時必須非常小心,因為這樣做會導致共享相同ArrayBuffer 的所有TypedArray 和Buffer 實例變得不可用。
const ab = new ArrayBuffer(10);
const u1 = new Uint8Array(ab);
const u2 = new Uint16Array(ab);
console.log(u2.length);  // prints 5
port.postMessage(u1, [u1.buffer]);
console.log(u2.length);  // prints 0
對於Buffer 實例,具體而言,底層ArrayBuffer 是否可以傳輸或克隆完全取決於實例的創建方式,而這通常無法可靠地確定。
ArrayBuffer 可以用  標記,以指示它應該始終被克隆並且永遠不會轉移。markAsUntransferable() 
根據 Buffer 實例的創建方式,它可能擁有也可能不擁有其底層 ArrayBuffer 。除非已知 Buffer 實例擁有它,否則不得轉移 ArrayBuffer。特別是,對於從內部 Buffer 池創建的 Buffer(例如使用 Buffer.from() 或 Buffer.allocUnsafe() ),無法傳輸它們並且它們總是被克隆,這會發送整個 Buffer 的副本水池。此行為可能會帶來意外的更高內存使用率和可能的安全問題。
有關Buffer 池的更多詳細信息,請參閱 。Buffer.allocUnsafe() 
使用 Buffer.alloc() 或 Buffer.allocUnsafeSlow() 創建的 Buffer 實例的 ArrayBuffer 始終可以傳輸,但這樣做會使這些 ArrayBuffer 的所有其他現有視圖不可用。
使用原型、類和訪問器克隆對象時的注意事項#
因為對象克隆使用 HTML structured clone algorithm ,所以不保留不可枚舉的屬性、屬性訪問器和對象原型。特別是,  對象將在接收端被讀取為普通的 Buffer   s,並且 JavaScript 類的實例將被克隆為普通的 JavaScript 對象。Uint8Array 
const b = Symbol('b');
class Foo {
  #a = 1;
  constructor() {
    this[b] = 2;
    this.c = 3;
  }
  get d() { return 4; }
}
const { port1, port2 } = new MessageChannel();
port1.onmessage = ({ data }) => console.log(data);
port2.postMessage(new Foo());
// Prints: { c: 3 }
此限製擴展到許多內置對象,例如全局 URL 對象:
const { port1, port2 } = new MessageChannel();
port1.onmessage = ({ data }) => console.log(data);
port2.postMessage(new URL('https://example.org'));
// Prints: { }
相關用法
- Node.js pop()用法及代碼示例
 - Node.js process.stdin用法及代碼示例
 - Node.js process.arch()用法及代碼示例
 - Node.js path.basename()用法及代碼示例
 - Node.js process.nextTick(callback[, ...args])用法及代碼示例
 - Node.js process.noDeprecation用法及代碼示例
 - Node.js process.setUncaughtExceptionCaptureCallback()用法及代碼示例
 - Node.js process.execPath用法及代碼示例
 - Node.js process.getgid()用法及代碼示例
 - Node.js process.setgid(id)用法及代碼示例
 - Node.js promiseHooks.createHook(callbacks)用法及代碼示例
 - Node.js process.chdir(directory)用法及代碼示例
 - Node.js process.setgid()用法及代碼示例
 - Node.js promiseHooks.onAfter(after)用法及代碼示例
 - Node.js process.getuid()用法及代碼示例
 - Node.js process.ppid用法及代碼示例
 - Node.js push()用法及代碼示例
 - Node.js process.report.reportOnSignal用法及代碼示例
 - Node.js process.report.directory用法及代碼示例
 - Node.js process.umask(mask)用法及代碼示例
 - Node.js performance.eventLoopUtilization([utilization1[, utilization2]])用法及代碼示例
 - Node.js process.setgroups(groups)用法及代碼示例
 - Node.js process.emitWarning()用法及代碼示例
 - Node.js path.resolve()用法及代碼示例
 - Node.js process.setegid(id)用法及代碼示例
 
注:本文由純淨天空篩選整理自nodejs.org大神的英文原創作品 port.postMessage(value[, transferList])。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。
