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 类型的实例,例如RegExp
s、BigInt
s、Map
s、Set
s 等。value
可能包含类型化数组,两者都使用ArrayBuffer
s 和SharedArrayBuffer
s。value
可能包含WebAssembly.Module
value
不得包含除以下内容之外的本机(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])。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。