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])。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。