port.postMessage(value[, transferList])
value
<any>transferList
<Object[]>
向该通道的接收端发送 JavaScript 值。
value
的传输方式与 HTML 结构化克隆算法兼容。
特别是与 JSON
的显着区别是:
value
可能包含循环引用。value
可能包含内置 JS 类型的实例,例如RegExp
、BigInt
、Map
、Set
等。value
可能包含类型化数组,都使用ArrayBuffer
和SharedArrayBuffer
。value
可能包含WebAssembly.Module
实例。value
可能不包含原生 (C++ 支持) 对象,除了:
const { MessageChannel } = require('node:worker_threads');
const { port1, port2 } = new MessageChannel();
port1.on('message', (message) => console.log(message));
const circularData = {};
circularData.foo = circularData;
// 打印: { foo: [Circular] }
port2.postMessage(circularData);
transferList
可能是 ArrayBuffer
、MessagePort
和 FileHandle
对象的列表。
传输后,它们在通道的发送端不再可用(即使它们不包含在 value
中)。
与子进程不同,当前不支持传输句柄,例如网络套接字。
如果 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 ]);
// 此发送 `uint8Array` 的副本:
port2.postMessage(uint8Array);
// 这不会复制数据,但会使 `uint8Array` 无法使用:
port2.postMessage(uint8Array, [ uint8Array.buffer ]);
// `sharedUint8Array` 的内存
// 可以从 `.on('message')` 收到的原件和副本中访问:
const sharedUint8Array = new Uint8Array(new SharedArrayBuffer(4));
port2.postMessage(sharedUint8Array);
// 这会将新创建的消息端口传输到接收器。
// 例如,这可用于在作为同一父线程的子线程的多个 `Worker` 线程之间
// 创建通信通道。
const otherChannel = new MessageChannel();
port2.postMessage({ port: otherChannel.port1 }, [ otherChannel.port1 ]);
消息对象立即克隆,发布后可修改,无副作用。
关于此 API 背后的序列化和反序列化机制的更多信息,请参见 node:v8
模块的序列化 API。
value
<any>transferList
<Object[]>
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.
In particular, the significant differences to JSON
are:
value
may contain circular references.value
may contain instances of builtin JS types such asRegExp
s,BigInt
s,Map
s,Set
s, etc.value
may contain typed arrays, both usingArrayBuffer
s andSharedArrayBuffer
s.value
may containWebAssembly.Module
instances.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
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.
If value
contains SharedArrayBuffer
instances, those are accessible
from either thread. They cannot be listed in transferList
.
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.
For more information on the serialization and deserialization mechanisms
behind this API, see the serialization API of the node:v8
module.