value{any}transferList{Object[]}
发送一个JavaScript值给一个接收端。
value 使用兼容 [HTML结构化克隆算法][] 的方式传输。
它与一般 JSON 的显著区别:
value可以包含循环引用。value可以包含一些内建JS类型,例如:RegExp,BigInt,Map,Set等。value可以包含基于ArrayBuffer和SharedArrayBuffer的类型数组。value可以包含 [WebAssembly.Module][] 实例。value不能包含 native(需C++模块支持的) 对象, 但以下除外:MessagePort、[FileHandle][] 和 [KeyObject][]。
const { MessageChannel } = require('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 中)。
不同于[child processes][],转移像socket连接这样的句柄(handle)目前尚不支持。
如果 value 包含 [SharedArrayBuffer][] 实例,
则这些实例(的内存)将可以被另一个线程直接访问。
并且他们无法被放入 transferList。
value 可以包含 ArrayBuffer 实例,但可以不把他们放入
transferList;此时,底层内存将被拷贝而非转移。
const { MessageChannel } = require('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` 的内存可以同时被发送端和接收端访问const sharedUint8Array = new Uint8Array(new SharedArrayBuffer(4));port2.postMessage(sharedUint8Array);// 发送一个 `MessagePort` 给接收者// 可以被用来让衍生的子工作线程之间互相通信const otherChannel = new MessageChannel();port2.postMessage({ port: otherChannel.port1 }, [ otherChannel.port1 ]);
由于使用结构化克隆算法来克隆对象,
不可枚举属性、属性访问器、对象原型将无法被保留。
需要特别注意,[Buffer][] 对象在接收端会以 [Uint8Array][] 类型被读取。
发送后对象会被立即克隆,之后的修改不会造成任何影响。
更多关于此API的序列化和反序列化机制的内容,
参考 [serialization API of the v8 module][v8.serdes]。
