port.postMessage(value[, transferList])
value<any>transferList<Object[]>
将一个 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可能包含内置 JS 类型的实例,例如RegExp、BigInt、Map、Set等。value可能包含类型化数组,这些数组可以使用ArrayBuffer或SharedArrayBuffer。value可能包含WebAssembly.Module个实例。value可能不包含除以下之外的本地(C++ 支撑的)对象:- <CryptoKey>,
- <FileHandle>,
- <Histogram>,
- <KeyObject>,
- <MessagePort>,
- <net.BlockList>,
- <net.Server>(仅限 TCP,当列在
transferList中时), - <net.Socket>(仅限 TCP,当在
transferList中列出时), - <net.SocketAddress>,
- <X509Certificate>。
import { MessageChannel } from '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);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、<net.Server> 和 <net.Socket> 对象的列表。传输后,它们在通道的发送端就不能再使用了(即使它们不在 value 中)。
转移一个 <net.Server> 会把它的监听套接字——连同在接收队列中的任何待处理连接——移动到接收线程的事件循环中。转移一个 <net.Socket> 会移动一个单独的连接;这个套接字必须是新接受或新创建的 TCP 连接,而且还没有开始读取,也没有缓冲数据,否则 postMessage() 会抛出 ERR_WORKER_HANDLE_NOT_TRANSFERABLE。这样就可以在一个线程上接受连接,然后把它们分配到一组工作线程中。只支持 TCP 句柄。
🌐 Transferring a <net.Server> moves its listening socket — together with any
pending connections in the accept queue — to the receiving thread's event loop.
Transferring a <net.Socket> moves a single connection; the socket must be a
freshly accepted or created TCP connection that has not yet started reading and
has no buffered data, otherwise postMessage() throws
ERR_WORKER_HANDLE_NOT_TRANSFERABLE. This makes it possible to accept
connections on one thread and distribute them across a pool of worker threads.
Only TCP handles are supported.
如果 value 包含 <SharedArrayBuffer> 个实例,这些实例可以从任一线程访问。它们不能列在 transferList 中。
🌐 If value contains <SharedArrayBuffer> instances, those are accessible
from either thread. They cannot be listed in transferList.
value 仍可能包含未在 transferList 中的 ArrayBuffer 实例;在这种情况下,底层内存是被复制而不是移动的。
import { MessageChannel } from '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 ]);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.