port.postMessage(value[, transferList])


向该通道的接收端发送 JavaScript 值。value 以与 HTML 结构化克隆算法 兼容的方式传输。

¥Sends a JavaScript value to the receiving side of this channel. value is transferred in a way which is compatible with the HTML structured clone algorithm.

特别是与 JSON 的显着区别是:

¥In particular, the significant differences to JSON are:

  • value 可能包含循环引用。

    ¥value may contain circular references.

  • value 可能包含内置 JS 类型的实例,例如 RegExpBigIntMapSet 等。

    ¥value may contain instances of builtin JS types such as RegExps, BigInts, Maps, Sets, etc.

  • value 可能包含类型化数组,同时使用 ArrayBufferSharedArrayBuffer

    ¥value may contain typed arrays, both using ArrayBuffers and SharedArrayBuffers.

  • value 可能包含 WebAssembly.Module 实例。

    ¥value may contain WebAssembly.Module instances.

  • value 可能不包含原生 (C++ 支持) 对象,除了:

    ¥value may not contain native (C++-backed) objects other than:

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 可能是 ArrayBufferMessagePortFileHandle 对象的列表。传输后,它们在通道的发送端不再可用(即使它们不包含在 value 中)。与 子进程 不同,目前不支持传输句柄,例如网络套接字。

¥transferList may be a list of ArrayBuffer, MessagePort, and FileHandle objects. After transferring, they are not usable on the sending side of the channel anymore (even if they are not contained in value). Unlike with child processes, transferring handles such as network sockets is currently not supported.

如果 value 包含 SharedArrayBuffer 实例,则可以从任一线程访问它们。它们不能在 transferList 中列出。

¥If value contains SharedArrayBuffer instances, those are accessible from either thread. They cannot be listed in transferList.

value 可能仍然包含不在 transferList 中的 ArrayBuffer 个实例;在这种情况下,底层内存被复制而不是移动。

¥value may still contain ArrayBuffer instances that are not in transferList; in that case, the underlying memory is copied rather than moved.

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 ]); 

消息对象立即克隆,发布后可修改,无副作用。

¥The message object is cloned immediately, and can be modified after posting without having side effects.

有关此 API 背后的序列化和反序列化机制的更多信息,请参阅 node:v8 模块的序列化 API

¥For more information on the serialization and deserialization mechanisms behind this API, see the serialization API of the node:v8 module.