- assert 断言
- async_hooks 异步钩子
- async_hooks/context 异步上下文
- buffer 缓冲区
- C++插件
- C/C++插件(使用 Node-API)
- C++嵌入器
- child_process 子进程
- cluster 集群
- CLI 命令行
- console 控制台
- Corepack 核心包
- crypto 加密
- crypto/webcrypto 网络加密
- debugger 调试器
- deprecation 弃用
- dgram 数据报
- diagnostics_channel 诊断通道
- dns 域名服务器
- domain 域
- Error 错误
- events 事件触发器
- fs 文件系统
- global 全局变量
- http 超文本传输协议
- http2 超文本传输协议 2.0
- https 安全超文本传输协议
- inspector 检查器
- Intl 国际化
- module 模块
- module/cjs CommonJS 模块
- module/esm ECMAScript 模块
- module/package 包模块
- net 网络
- os 操作系统
- path 路径
- perf_hooks 性能钩子
- permission 权限
- process 进程
- punycode 域名代码
- querystring 查询字符串
- readline 逐行读取
- repl 交互式解释器
- report 诊断报告
- stream 流
- stream/web 网络流
- string_decoder 字符串解码器
- test 测试
- timers 定时器
- tls 安全传输层
- trace_events 跟踪事件
- tty 终端
- url 网址
- util 实用工具
- v8 引擎
- vm 虚拟机
- wasi 网络汇编系统接口
- worker_threads 工作线程
- zlib 压缩
Node.js v16.20.0 文档
- Node.js v16.20.0
-
目录
- V8
v8.cachedDataVersionTag()
v8.getHeapCodeStatistics()
v8.getHeapSnapshot()
v8.getHeapSpaceStatistics()
v8.getHeapStatistics()
v8.setFlagsFromString(flags)
v8.stopCoverage()
v8.takeCoverage()
v8.writeHeapSnapshot([filename])
v8.setHeapSnapshotNearHeapLimit(limit)
- 序列化 API
v8.serialize(value)
v8.deserialize(buffer)
- 类:
v8.Serializer
new Serializer()
serializer.writeHeader()
serializer.writeValue(value)
serializer.releaseBuffer()
serializer.transferArrayBuffer(id, arrayBuffer)
serializer.writeUint32(value)
serializer.writeUint64(hi, lo)
serializer.writeDouble(value)
serializer.writeRawBytes(buffer)
serializer._writeHostObject(object)
serializer._getDataCloneError(message)
serializer._getSharedArrayBufferId(sharedArrayBuffer)
serializer._setTreatArrayBufferViewsAsHostObjects(flag)
- 类:
v8.Deserializer
new Deserializer(buffer)
deserializer.readHeader()
deserializer.readValue()
deserializer.transferArrayBuffer(id, arrayBuffer)
deserializer.getWireFormatVersion()
deserializer.readUint32()
deserializer.readUint64()
deserializer.readDouble()
deserializer.readRawBytes(length)
deserializer._readHostObject()
- 类:
v8.DefaultSerializer
- 类:
v8.DefaultDeserializer
- Promise 钩子
- 启动快照 API
- V8
-
导航
- assert 断言
- async_hooks 异步钩子
- async_hooks/context 异步上下文
- buffer 缓冲区
- C++插件
- C/C++插件(使用 Node-API)
- C++嵌入器
- child_process 子进程
- cluster 集群
- CLI 命令行
- console 控制台
- Corepack 核心包
- crypto 加密
- crypto/webcrypto 网络加密
- debugger 调试器
- deprecation 弃用
- dgram 数据报
- diagnostics_channel 诊断通道
- dns 域名服务器
- domain 域
- Error 错误
- events 事件触发器
- fs 文件系统
- global 全局变量
- http 超文本传输协议
- http2 超文本传输协议 2.0
- https 安全超文本传输协议
- inspector 检查器
- Intl 国际化
- module 模块
- module/cjs CommonJS 模块
- module/esm ECMAScript 模块
- module/package 包模块
- net 网络
- os 操作系统
- path 路径
- perf_hooks 性能钩子
- permission 权限
- process 进程
- punycode 域名代码
- querystring 查询字符串
- readline 逐行读取
- repl 交互式解释器
- report 诊断报告
- stream 流
- stream/web 网络流
- string_decoder 字符串解码器
- test 测试
- timers 定时器
- tls 安全传输层
- trace_events 跟踪事件
- tty 终端
- url 网址
- util 实用工具
- v8 引擎
- vm 虚拟机
- wasi 网络汇编系统接口
- worker_threads 工作线程
- zlib 压缩
- 其他版本
V8#
源代码: lib/v8.js
node:v8
模块公开了特定于 Node.js 二进制文件中内置的 V8 版本的 API。可以使用以下方式访问它:
¥The node:v8
module exposes APIs that are specific to the version of V8
built into the Node.js binary. It can be accessed using:
const v8 = require('node:v8');
v8.cachedDataVersionTag()
#
返回表示从 V8 版本、命令行标志、以及检测到的 CPU 特性派生的版本标签的整数。这对于判断 vm.Script
cachedData
缓冲区是否与此 V8 实例兼容很有用。
¥Returns an integer representing a version tag derived from the V8 version,
command-line flags, and detected CPU features. This is useful for determining
whether a vm.Script
cachedData
buffer is compatible with this instance
of V8.
console.log(v8.cachedDataVersionTag()); // 3947234607
// The value returned by v8.cachedDataVersionTag() is derived from the V8
// version, command-line flags, and detected CPU features. Test that the value
// does indeed update when flags are toggled.
v8.setFlagsFromString('--allow_natives_syntax');
console.log(v8.cachedDataVersionTag()); // 183726201
v8.getHeapCodeStatistics()
#
返回具有以下属性的对象:
¥Returns an object with the following properties:
-
code_and_metadata_size
<number> -
bytecode_and_metadata_size
<number> -
external_script_source_size
<number>
{
code_and_metadata_size: 212208,
bytecode_and_metadata_size: 161368,
external_script_source_size: 1410794
}
v8.getHeapSnapshot()
#
-
返回:<stream.Readable> 包含 V8 堆快照的可读流
¥Returns: <stream.Readable> A Readable Stream containing the V8 heap snapshot
生成当前 V8 堆的快照并返回可用于读取 JSON 序列化表示的可读流。此 JSON 流格式旨在与 Chrome 开发者工具等工具一起使用。JSON 模式未记录并且特定于 V8 引擎。因此,模式可能会从 V8 的一个版本更改为下一个版本。
¥Generates a snapshot of the current V8 heap and returns a Readable Stream that may be used to read the JSON serialized representation. This JSON stream format is intended to be used with tools such as Chrome DevTools. The JSON schema is undocumented and specific to the V8 engine. Therefore, the schema may change from one version of V8 to the next.
创建堆快照需要的内存大约是创建快照时堆大小的两倍。这会导致 OOM 杀手终止进程的风险。
¥Creating a heap snapshot requires memory about twice the size of the heap at the time the snapshot is created. This results in the risk of OOM killers terminating the process.
生成快照是一个同步的操作,它会根据堆大小在一段时间内阻塞事件循环。
¥Generating a snapshot is a synchronous operation which blocks the event loop for a duration depending on the heap size.
// Print heap snapshot to the console
const v8 = require('node:v8');
const stream = v8.getHeapSnapshot();
stream.pipe(process.stdout);
v8.getHeapSpaceStatistics()
#
-
返回:<Object[]>
¥Returns: <Object[]>
返回有关 V8 堆空间的统计信息,即构成 V8 堆的片段。堆空间的排序和堆空间的可用性都无法保证,因为统计信息是通过 V8 GetHeapSpaceStatistics
函数提供的,并且可能会从一个 V8 版本更改为下一个版本。
¥Returns statistics about the V8 heap spaces, i.e. the segments which make up
the V8 heap. Neither the ordering of heap spaces, nor the availability of a
heap space can be guaranteed as the statistics are provided via the V8
GetHeapSpaceStatistics
function and may change from one V8 version to the
next.
返回的值是包含以下属性的对象数组
¥The value returned is an array of objects containing the following properties:
-
space_name
<string> -
space_size
<number> -
space_used_size
<number> -
space_available_size
<number> -
physical_space_size
<number>
[
{
"space_name": "new_space",
"space_size": 2063872,
"space_used_size": 951112,
"space_available_size": 80824,
"physical_space_size": 2063872
},
{
"space_name": "old_space",
"space_size": 3090560,
"space_used_size": 2493792,
"space_available_size": 0,
"physical_space_size": 3090560
},
{
"space_name": "code_space",
"space_size": 1260160,
"space_used_size": 644256,
"space_available_size": 960,
"physical_space_size": 1260160
},
{
"space_name": "map_space",
"space_size": 1094160,
"space_used_size": 201608,
"space_available_size": 0,
"physical_space_size": 1094160
},
{
"space_name": "large_object_space",
"space_size": 0,
"space_used_size": 0,
"space_available_size": 1490980608,
"physical_space_size": 0
}
]
v8.getHeapStatistics()
#
返回具有以下属性的对象:
¥Returns an object with the following properties:
-
total_heap_size
<number> -
total_heap_size_executable
<number> -
total_physical_size
<number> -
total_available_size
<number> -
used_heap_size
<number> -
heap_size_limit
<number> -
malloced_memory
<number> -
peak_malloced_memory
<number> -
does_zap_garbage
<number> -
number_of_native_contexts
<number> -
number_of_detached_contexts
<number> -
total_global_handles_size
<number> -
used_global_handles_size
<number> -
external_memory
<number>
does_zap_garbage
是 0/1 布尔值,表示是否启用了 --zap_code_space
选项。这使得 V8 使用位模式覆盖堆垃圾。RSS 占用空间(常驻集大小)变得更大,因为它不断接触所有堆页面,这使得它们不太可能被操作系统换出。
¥does_zap_garbage
is a 0/1 boolean, which signifies whether the
--zap_code_space
option is enabled or not. This makes V8 overwrite heap
garbage with a bit pattern. The RSS footprint (resident set size) gets bigger
because it continuously touches all heap pages and that makes them less likely
to get swapped out by the operating system.
number_of_native_contexts
native_context 的值是当前活动的顶层上下文的数量。随着时间的推移此数字的增加表示内存泄漏。
¥number_of_native_contexts
The value of native_context is the number of the
top-level contexts currently active. Increase of this number over time indicates
a memory leak.
number_of_detached_contexts
detached_context 的值是已分离但尚未进行垃圾收集的上下文的数量。此数字非零表示潜在的内存泄漏。
¥number_of_detached_contexts
The value of detached_context is the number
of contexts that were detached and not yet garbage collected. This number
being non-zero indicates a potential memory leak.
total_global_handles_size
Total_global_handles_size 的值是 V8 全局句柄的总内存大小。
¥total_global_handles_size
The value of total_global_handles_size is the
total memory size of V8 global handles.
used_global_handles_size
used_global_handles_size 的值是 V8 全局句柄的已用内存大小。
¥used_global_handles_size
The value of used_global_handles_size is the
used memory size of V8 global handles.
external_memory
external_memory 的值是数组缓冲区和外部字符串的内存大小。
¥external_memory
The value of external_memory is the memory size of array
buffers and external strings.
{
total_heap_size: 7326976,
total_heap_size_executable: 4194304,
total_physical_size: 7326976,
total_available_size: 1152656,
used_heap_size: 3476208,
heap_size_limit: 1535115264,
malloced_memory: 16384,
peak_malloced_memory: 1127496,
does_zap_garbage: 0,
number_of_native_contexts: 1,
number_of_detached_contexts: 0,
total_global_handles_size: 8192,
used_global_handles_size: 3296,
external_memory: 318824
}
v8.setFlagsFromString(flags)
#
flags
<string>
v8.setFlagsFromString()
方法可用于以编程方式设置 V8 命令行标志。此方法需谨慎使用。在 VM 启动后更改设置可能会导致不可预测的行为,包括崩溃和数据丢失;或者它可能什么都不做。
¥The v8.setFlagsFromString()
method can be used to programmatically set
V8 command-line flags. This method should be used with care. Changing settings
after the VM has started may result in unpredictable behavior, including
crashes and data loss; or it may simply do nothing.
可以通过运行 node --v8-options
来确定 Node.js 版本可用的 V8 选项。
¥The V8 options available for a version of Node.js may be determined by running
node --v8-options
.
用法:
¥Usage:
// Print GC events to stdout for one minute.
const v8 = require('node:v8');
v8.setFlagsFromString('--trace_gc');
setTimeout(() => { v8.setFlagsFromString('--notrace_gc'); }, 60e3);
v8.stopCoverage()
#
v8.stopCoverage()
方法允许用户停止 NODE_V8_COVERAGE
启动的覆盖收集,以便 V8 可以释放执行计数记录并优化代码。如果用户想按需收集覆盖范围,可以与 v8.takeCoverage()
结合使用。
¥The v8.stopCoverage()
method allows the user to stop the coverage collection
started by NODE_V8_COVERAGE
, so that V8 can release the execution count
records and optimize code. This can be used in conjunction with
v8.takeCoverage()
if the user wants to collect the coverage on demand.
v8.takeCoverage()
#
v8.takeCoverage()
方法允许用户按需将 NODE_V8_COVERAGE
开始的覆盖写入磁盘。此方法可以在进程的生命周期内多次调用。每次执行计数器将被重置,并且新的覆盖报告将写入 NODE_V8_COVERAGE
指定的目录。
¥The v8.takeCoverage()
method allows the user to write the coverage started by
NODE_V8_COVERAGE
to disk on demand. This method can be invoked multiple
times during the lifetime of the process. Each time the execution counter will
be reset and a new coverage report will be written to the directory specified
by NODE_V8_COVERAGE
.
当进程即将退出时,除非在进程退出前调用 v8.stopCoverage()
,否则最后一个覆盖仍会写入磁盘。
¥When the process is about to exit, one last coverage will still be written to
disk unless v8.stopCoverage()
is invoked before the process exits.
v8.writeHeapSnapshot([filename])
#
-
filename
<string> 要保存 V8 堆快照的文件路径。如果不指定,则会生成格式为'Heap-${yyyymmdd}-${hhmmss}-${pid}-${thread_id}.heapsnapshot'
的文件名,其中{pid}
是 Node.js 进程的 PID,当writeHeapSnapshot()
从 Node.js 主线程调用时,{thread_id}
将是0
或工作线程的 id。¥
filename
<string> The file path where the V8 heap snapshot is to be saved. If not specified, a file name with the pattern'Heap-${yyyymmdd}-${hhmmss}-${pid}-${thread_id}.heapsnapshot'
will be generated, where{pid}
will be the PID of the Node.js process,{thread_id}
will be0
whenwriteHeapSnapshot()
is called from the main Node.js thread or the id of a worker thread. -
返回:<string> 保存快照的文件名。
¥Returns: <string> The filename where the snapshot was saved.
生成当前 V8 堆的快照并将其写入 JSON 文件。此文件旨在与 Chrome 开发者工具等工具一起使用JSON 模式未记录并且特定于 V8 引擎,并且可能会从 V8 的一个版本更改为下一个版本。
¥Generates a snapshot of the current V8 heap and writes it to a JSON file. This file is intended to be used with tools such as Chrome DevTools. The JSON schema is undocumented and specific to the V8 engine, and may change from one version of V8 to the next.
堆快照特定于单个 V8 隔离。使用 工作线程 时,从主线程生成的堆快照将不包含有关工作进程的任何信息,反之亦然。
¥A heap snapshot is specific to a single V8 isolate. When using worker threads, a heap snapshot generated from the main thread will not contain any information about the workers, and vice versa.
创建堆快照需要的内存大约是创建快照时堆大小的两倍。这会导致 OOM 杀手终止进程的风险。
¥Creating a heap snapshot requires memory about twice the size of the heap at the time the snapshot is created. This results in the risk of OOM killers terminating the process.
生成快照是一个同步的操作,它会根据堆大小在一段时间内阻塞事件循环。
¥Generating a snapshot is a synchronous operation which blocks the event loop for a duration depending on the heap size.
const { writeHeapSnapshot } = require('node:v8');
const {
Worker,
isMainThread,
parentPort
} = require('node:worker_threads');
if (isMainThread) {
const worker = new Worker(__filename);
worker.once('message', (filename) => {
console.log(`worker heapdump: ${filename}`);
// Now get a heapdump for the main thread.
console.log(`main thread heapdump: ${writeHeapSnapshot()}`);
});
// Tell the worker to create a heapdump.
worker.postMessage('heapdump');
} else {
parentPort.once('message', (message) => {
if (message === 'heapdump') {
// Generate a heapdump for the worker
// and return the filename to the parent.
parentPort.postMessage(writeHeapSnapshot());
}
});
}
v8.setHeapSnapshotNearHeapLimit(limit)
#
¥Stability: 1 - Experimental
limit
<integer>
如果 --heapsnapshot-near-heap-limit
已经从命令行设置或 API 被多次调用,则 API 是无操作的。limit
必须是正整数。有关详细信息,请参阅 --heapsnapshot-near-heap-limit
。
¥The API is a no-op if --heapsnapshot-near-heap-limit
is already set from the
command line or the API is called more than once. limit
must be a positive
integer. See --heapsnapshot-near-heap-limit
for more information.
序列化 API#
¥Serialization API
序列化 API 提供了以与 HTML 结构化克隆算法 兼容的方式序列化 JavaScript 值的方法。
¥The serialization API provides means of serializing JavaScript values in a way that is compatible with the HTML structured clone algorithm.
格式是向后兼容的(即可以安全地存储到磁盘)。相同的 JavaScript 值可能会导致不同的序列化输出。
¥The format is backward-compatible (i.e. safe to store to disk). Equal JavaScript values may result in different serialized output.
v8.serialize(value)
#
使用 DefaultSerializer
将 value
序列化到缓冲区中。
¥Uses a DefaultSerializer
to serialize value
into a buffer.
尝试序列化需要大于 buffer.constants.MAX_LENGTH
的缓冲区的大对象时,则将抛出 ERR_BUFFER_TOO_LARGE
。
¥ERR_BUFFER_TOO_LARGE
will be thrown when trying to
serialize a huge object which requires buffer
larger than buffer.constants.MAX_LENGTH
.
v8.deserialize(buffer)
#
-
buffer
<Buffer> | <TypedArray> | <DataView>serialize()
返回的缓冲区。¥
buffer
<Buffer> | <TypedArray> | <DataView> A buffer returned byserialize()
.
使用带有默认选项的 DefaultDeserializer
从缓冲区读取 JS 值。
¥Uses a DefaultDeserializer
with default options to read a JS value
from a buffer.
类:v8.Serializer
#
¥Class: v8.Serializer
new Serializer()
#
创建新的 Serializer
对象。
¥Creates a new Serializer
object.
serializer.writeHeader()
#
写出标头,其中包括序列化格式版本。
¥Writes out a header, which includes the serialization format version.
serializer.writeValue(value)
#
value
<any>
序列化 JavaScript 值并将序列化的表示添加到内部缓冲区。
¥Serializes a JavaScript value and adds the serialized representation to the internal buffer.
如果无法序列化 value
,则抛出错误。
¥This throws an error if value
cannot be serialized.
serializer.releaseBuffer()
#
返回存储的内部缓冲区。释放缓冲区后不应使用此序列化器。如果先前的写入失败,则调用此方法会导致未定义的行为。
¥Returns the stored internal buffer. This serializer should not be used once the buffer is released. Calling this method results in undefined behavior if a previous write has failed.
serializer.transferArrayBuffer(id, arrayBuffer)
#
-
id
<integer> 32 位无符号整数。¥
id
<integer> A 32-bit unsigned integer. -
arrayBuffer
<ArrayBuffer>ArrayBuffer
实例。¥
arrayBuffer
<ArrayBuffer> AnArrayBuffer
instance.
将 ArrayBuffer
标记为将其内容传输到带外。将反序列化上下文中对应的 ArrayBuffer
传给 deserializer.transferArrayBuffer()
。
¥Marks an ArrayBuffer
as having its contents transferred out of band.
Pass the corresponding ArrayBuffer
in the deserializing context to
deserializer.transferArrayBuffer()
.
serializer.writeUint32(value)
#
value
<integer>
写入原始的 32 位无符号整数。用于自定义的 serializer._writeHostObject()
内部。
¥Write a raw 32-bit unsigned integer.
For use inside of a custom serializer._writeHostObject()
.
serializer.writeUint64(hi, lo)
#
写入原始的 64 位无符号整数,分成高和低 32 位部分。用于自定义的 serializer._writeHostObject()
内部。
¥Write a raw 64-bit unsigned integer, split into high and low 32-bit parts.
For use inside of a custom serializer._writeHostObject()
.
serializer.writeDouble(value)
#
value
<number>
写入 JS number
值。用于自定义的 serializer._writeHostObject()
内部。
¥Write a JS number
value.
For use inside of a custom serializer._writeHostObject()
.
serializer.writeRawBytes(buffer)
#
buffer
<Buffer> | <TypedArray> | <DataView>
将原始字节写入序列化器的内部缓冲区。反序列化器需要一种方法来计算缓冲区的长度。用于自定义的 serializer._writeHostObject()
内部。
¥Write raw bytes into the serializer's internal buffer. The deserializer
will require a way to compute the length of the buffer.
For use inside of a custom serializer._writeHostObject()
.
serializer._writeHostObject(object)
#
object
<Object>
调用此方法来写入某种宿主对象,即由原生 C++ 绑定创建的对象。如果无法序列化 object
,则应抛出合适的异常。
¥This method is called to write some kind of host object, i.e. an object created
by native C++ bindings. If it is not possible to serialize object
, a suitable
exception should be thrown.
此方法不存在于 Serializer
类本身,但可以由子类提供。
¥This method is not present on the Serializer
class itself but can be provided
by subclasses.
serializer._getDataCloneError(message)
#
message
<string>
调用此方法生成错误对象,当无法克隆对象时将抛出该错误对象。
¥This method is called to generate error objects that will be thrown when an object can not be cloned.
此方法默认为 Error
构造函数,并且可以在子类上覆盖。
¥This method defaults to the Error
constructor and can be overridden on
subclasses.
serializer._getSharedArrayBufferId(sharedArrayBuffer)
#
sharedArrayBuffer
<SharedArrayBuffer>
此方法在序列化器要序列化 SharedArrayBuffer
对象时被调用。它必须为对象返回无符号的 32 位整数 ID,如果此 SharedArrayBuffer
已被序列化,则使用相同的 ID。当反序列化时,此 ID 会传给 deserializer.transferArrayBuffer()
。
¥This method is called when the serializer is going to serialize a
SharedArrayBuffer
object. It must return an unsigned 32-bit integer ID for
the object, using the same ID if this SharedArrayBuffer
has already been
serialized. When deserializing, this ID will be passed to
deserializer.transferArrayBuffer()
.
如果对象无法序列化,则应抛出异常。
¥If the object cannot be serialized, an exception should be thrown.
此方法不存在于 Serializer
类本身,但可以由子类提供。
¥This method is not present on the Serializer
class itself but can be provided
by subclasses.
serializer._setTreatArrayBufferViewsAsHostObjects(flag)
#
指示是否将 TypedArray
和 DataView
对象视为宿主对象,即将它们传给 serializer._writeHostObject()
。
¥Indicate whether to treat TypedArray
and DataView
objects as
host objects, i.e. pass them to serializer._writeHostObject()
.
类:v8.Deserializer
#
¥Class: v8.Deserializer
new Deserializer(buffer)
#
-
buffer
<Buffer> | <TypedArray> | <DataView>serializer.releaseBuffer()
返回的缓冲区。¥
buffer
<Buffer> | <TypedArray> | <DataView> A buffer returned byserializer.releaseBuffer()
.
创建新的 Deserializer
对象。
¥Creates a new Deserializer
object.
deserializer.readHeader()
#
读取并验证标头(包括格式版本)。例如,可以拒绝无效或不受支持的有线格式。在这种情况下,会抛出 Error
。
¥Reads and validates a header (including the format version).
May, for example, reject an invalid or unsupported wire format. In that case,
an Error
is thrown.
deserializer.readValue()
#
从缓冲区反序列化 JavaScript 值并返回。
¥Deserializes a JavaScript value from the buffer and returns it.
deserializer.transferArrayBuffer(id, arrayBuffer)
#
-
id
<integer> 32 位无符号整数。¥
id
<integer> A 32-bit unsigned integer. -
arrayBuffer
<ArrayBuffer> | <SharedArrayBuffer>ArrayBuffer
实例。¥
arrayBuffer
<ArrayBuffer> | <SharedArrayBuffer> AnArrayBuffer
instance.
将 ArrayBuffer
标记为将其内容传输到带外。将序列化上下文中对应的 ArrayBuffer
传递给 serializer.transferArrayBuffer()
(或者在 SharedArrayBuffer
的情况下从 serializer._getSharedArrayBufferId()
返回 id
)。
¥Marks an ArrayBuffer
as having its contents transferred out of band.
Pass the corresponding ArrayBuffer
in the serializing context to
serializer.transferArrayBuffer()
(or return the id
from
serializer._getSharedArrayBufferId()
in the case of SharedArrayBuffer
s).
deserializer.getWireFormatVersion()
#
读取底层有线格式版本。可能主要用于读取旧的有线格式版本的旧版代码不能在 .readHeader()
之前调用。
¥Reads the underlying wire format version. Likely mostly to be useful to
legacy code reading old wire format versions. May not be called before
.readHeader()
.
deserializer.readUint32()
#
读取原始的 32 位无符号整数并返回。用于自定义的 deserializer._readHostObject()
内部。
¥Read a raw 32-bit unsigned integer and return it.
For use inside of a custom deserializer._readHostObject()
.
deserializer.readUint64()
#
-
返回:<integer[]>
¥Returns: <integer[]>
读取原始的 64 位无符号整数并将其作为具有两个 32 位无符号整数条目的数组 [hi, lo]
返回。用于自定义的 deserializer._readHostObject()
内部。
¥Read a raw 64-bit unsigned integer and return it as an array [hi, lo]
with two 32-bit unsigned integer entries.
For use inside of a custom deserializer._readHostObject()
.
deserializer.readDouble()
#
读取 JS number
值。用于自定义的 deserializer._readHostObject()
内部。
¥Read a JS number
value.
For use inside of a custom deserializer._readHostObject()
.
deserializer.readRawBytes(length)
#
从反序列化器的内部缓冲区读取原始字节。length
参数必须对应于传给 serializer.writeRawBytes()
的缓冲区的长度。用于自定义的 deserializer._readHostObject()
内部。
¥Read raw bytes from the deserializer's internal buffer. The length
parameter
must correspond to the length of the buffer that was passed to
serializer.writeRawBytes()
.
For use inside of a custom deserializer._readHostObject()
.
deserializer._readHostObject()
#
调用此方法来读取某种宿主对象,即由原生 C++ 绑定创建的对象。如果无法反序列化数据,则应抛出合适的异常。
¥This method is called to read some kind of host object, i.e. an object that is created by native C++ bindings. If it is not possible to deserialize the data, a suitable exception should be thrown.
此方法不存在于 Deserializer
类本身,但可以由子类提供。
¥This method is not present on the Deserializer
class itself but can be
provided by subclasses.
类:v8.DefaultSerializer
#
¥Class: v8.DefaultSerializer
Serializer
的子类,将 TypedArray
(特别是 Buffer
)和 DataView
对象序列化为宿主对象,并且只存储它们所引用的底层 ArrayBuffer
的一部分。
¥A subclass of Serializer
that serializes TypedArray
(in particular Buffer
) and DataView
objects as host objects, and only
stores the part of their underlying ArrayBuffer
s that they are referring to.
类:v8.DefaultDeserializer
#
¥Class: v8.DefaultDeserializer
DefaultSerializer
所写格式对应的 Deserializer
子类。
¥A subclass of Deserializer
corresponding to the format written by
DefaultSerializer
.
Promise 钩子#
¥Promise hooks
promiseHooks
接口可用于跟踪 promise 生命周期事件。要跟踪所有异步活动,请参阅 async_hooks
,它在内部使用此模块来生成 promise 生命周期事件以及其他异步资源的事件。请求的上下文管理参阅 AsyncLocalStorage
。
¥The promiseHooks
interface can be used to track promise lifecycle events.
To track all async activity, see async_hooks
which internally uses this
module to produce promise lifecycle events in addition to events for other
async resources. For request context management, see AsyncLocalStorage
.
import { promiseHooks } from 'node:v8';
// There are four lifecycle events produced by promises:
// The `init` event represents the creation of a promise. This could be a
// direct creation such as with `new Promise(...)` or a continuation such
// as `then()` or `catch()`. It also happens whenever an async function is
// called or does an `await`. If a continuation promise is created, the
// `parent` will be the promise it is a continuation from.
function init(promise, parent) {
console.log('a promise was created', { promise, parent });
}
// The `settled` event happens when a promise receives a resolution or
// rejection value. This may happen synchronously such as when using
// `Promise.resolve()` on non-promise input.
function settled(promise) {
console.log('a promise resolved or rejected', { promise });
}
// The `before` event runs immediately before a `then()` or `catch()` handler
// runs or an `await` resumes execution.
function before(promise) {
console.log('a promise is about to call a then handler', { promise });
}
// The `after` event runs immediately after a `then()` handler runs or when
// an `await` begins after resuming from another.
function after(promise) {
console.log('a promise is done calling a then handler', { promise });
}
// Lifecycle hooks may be started and stopped individually
const stopWatchingInits = promiseHooks.onInit(init);
const stopWatchingSettleds = promiseHooks.onSettled(settled);
const stopWatchingBefores = promiseHooks.onBefore(before);
const stopWatchingAfters = promiseHooks.onAfter(after);
// Or they may be started and stopped in groups
const stopHookSet = promiseHooks.createHook({
init,
settled,
before,
after
});
// To stop a hook, call the function returned at its creation.
stopWatchingInits();
stopWatchingSettleds();
stopWatchingBefores();
stopWatchingAfters();
stopHookSet();
promiseHooks.onInit(init)
#
-
init
<Function> 创建 promise 时要调用的init
回调。¥
init
<Function> Theinit
callback to call when a promise is created. -
返回:<Function> 调用以停止钩子。
¥Returns: <Function> Call to stop the hook.
init
钩子必须是普通函数。提供异步函数会抛出异常,因为它会产生无限的微任务循环。
¥The init
hook must be a plain function. Providing an async function will
throw as it would produce an infinite microtask loop.
import { promiseHooks } from 'node:v8';
const stop = promiseHooks.onInit((promise, parent) => {});
const { promiseHooks } = require('node:v8');
const stop = promiseHooks.onInit((promise, parent) => {});
promiseHooks.onSettled(settled)
#
-
settled
<Function> 当 promise 被解决或拒绝时调用的settled
回调。¥
settled
<Function> Thesettled
callback to call when a promise is resolved or rejected. -
返回:<Function> 调用以停止钩子。
¥Returns: <Function> Call to stop the hook.
settled
钩子必须是普通函数。提供异步函数会抛出异常,因为它会产生无限的微任务循环。
¥The settled
hook must be a plain function. Providing an async function will
throw as it would produce an infinite microtask loop.
import { promiseHooks } from 'node:v8';
const stop = promiseHooks.onSettled((promise) => {});
const { promiseHooks } = require('node:v8');
const stop = promiseHooks.onSettled((promise) => {});
promiseHooks.onBefore(before)
#
-
before
<Function> 在 promise 继续执行之前调用的before
回调。¥
before
<Function> Thebefore
callback to call before a promise continuation executes. -
返回:<Function> 调用以停止钩子。
¥Returns: <Function> Call to stop the hook.
before
钩子必须是普通函数。提供异步函数会抛出异常,因为它会产生无限的微任务循环。
¥The before
hook must be a plain function. Providing an async function will
throw as it would produce an infinite microtask loop.
import { promiseHooks } from 'node:v8';
const stop = promiseHooks.onBefore((promise) => {});
const { promiseHooks } = require('node:v8');
const stop = promiseHooks.onBefore((promise) => {});
promiseHooks.onAfter(after)
#
-
after
<Function> 在 promise 继续执行后调用的after
回调。¥
after
<Function> Theafter
callback to call after a promise continuation executes. -
返回:<Function> 调用以停止钩子。
¥Returns: <Function> Call to stop the hook.
after
钩子必须是普通函数。提供异步函数会抛出异常,因为它会产生无限的微任务循环。
¥The after
hook must be a plain function. Providing an async function will
throw as it would produce an infinite microtask loop.
import { promiseHooks } from 'node:v8';
const stop = promiseHooks.onAfter((promise) => {});
const { promiseHooks } = require('node:v8');
const stop = promiseHooks.onAfter((promise) => {});
promiseHooks.createHook(callbacks)
#
-
¥
callbacks
<Object> The Hook Callbacks to register-
init
<Function>init
回调。¥
init
<Function> Theinit
callback. -
before
<Function>before
回调。¥
before
<Function> Thebefore
callback. -
after
<Function>after
回调。¥
after
<Function> Theafter
callback. -
settled
<Function>settled
回调。¥
settled
<Function> Thesettled
callback.
-
-
返回:<Function> 用于禁用钩子
¥Returns: <Function> Used for disabling hooks
钩子回调必须是普通函数。提供异步函数会抛出异常,因为它会产生无限的微任务循环。
¥The hook callbacks must be plain functions. Providing async functions will throw as it would produce an infinite microtask loop.
注册要为每个 promise 的不同生命周期事件调用的函数。
¥Registers functions to be called for different lifetime events of each promise.
回调 init()
/before()
/after()
/settled()
在 promise 的生命周期内为各个事件调用。
¥The callbacks init()
/before()
/after()
/settled()
are called for the
respective events during a promise's lifetime.
所有回调都是可选的。例如,如果只需要跟踪 promise 的创建,则只需要传入 init
回调。可以传递给 callbacks
的所有函数的细节在 钩子回调 部分。
¥All callbacks are optional. For example, if only promise creation needs to
be tracked, then only the init
callback needs to be passed. The
specifics of all functions that can be passed to callbacks
is in the
Hook Callbacks section.
import { promiseHooks } from 'node:v8';
const stopAll = promiseHooks.createHook({
init(promise, parent) {}
});
const { promiseHooks } = require('node:v8');
const stopAll = promiseHooks.createHook({
init(promise, parent) {}
});
钩子回调#
¥Hook callbacks
promise 生命周期中的关键事件分为四个方面:创建 promise,在调用延续处理程序之前/之后或在等待期间,以及 promise 解决或拒绝时。
¥Key events in the lifetime of a promise have been categorized into four areas: creation of a promise, before/after a continuation handler is called or around an await, and when the promise resolves or rejects.
虽然这些钩子与 async_hooks
的钩子相似,但它们缺少 destroy
钩子。其他类型的异步资源通常代表套接字或文件描述符,它们具有不同的 "closed" 状态来表达 destroy
生命周期事件,而只要代码仍然可以访问它们,promise 就一直可用。垃圾收集跟踪用于使 promise 适合 async_hooks
事件模型,但是这种跟踪非常昂贵,而且它们甚至不一定会被垃圾收集。
¥While these hooks are similar to those of async_hooks
they lack a
destroy
hook. Other types of async resources typically represent sockets or
file descriptors which have a distinct "closed" state to express the destroy
lifecycle event while promises remain usable for as long as code can still
reach them. Garbage collection tracking is used to make promises fit into the
async_hooks
event model, however this tracking is very expensive and they may
not necessarily ever even be garbage collected.
因为 promise 是异步资源,其生命周期通过 promise 钩子机制进行跟踪,所以 init()
、before()
、after()
和 settled()
回调不能是异步函数,因为它们会创建更多会产生无限循环的 promise。
¥Because promises are asynchronous resources whose lifecycle is tracked
via the promise hooks mechanism, the init()
, before()
, after()
, and
settled()
callbacks must not be async functions as they create more
promises which would produce an infinite loop.
虽然此 API 用于将 promise 事件提供给 async_hooks
,但两者之间的顺序是未定义的。两个 API 都是多租户的,因此可以以相对于彼此的任何顺序产生事件。
¥While this API is used to feed promise events into async_hooks
, the
ordering between the two is undefined. Both APIs are multi-tenant
and therefore could produce events in any order relative to each other.
init(promise, parent)
#
-
promise
<Promise> 正在创建的 promise。¥
promise
<Promise> The promise being created. -
parent
<Promise> 如果适用,则 promise 从此继续。¥
parent
<Promise> The promise continued from, if applicable.
当构造 promise 时调用。这并不意味着会发生相应的 before
/after
事件,只是存在这种可能性。如果在没有获得继续的情况下创建了 promise,则会发生这种情况。
¥Called when a promise is constructed. This does not mean that corresponding
before
/after
events will occur, only that the possibility exists. This will
happen if a promise is created without ever getting a continuation.
before(promise)
#
promise
<Promise>
在 promise 继续执行之前调用。这可以是 then()
、catch()
或 finally()
句柄或 await
恢复的形式。
¥Called before a promise continuation executes. This can be in the form of
then()
, catch()
, or finally()
handlers or an await
resuming.
before
回调将被调用 0 到 N 次。如果 promise 没有继续进行,则 before
回调通常会被调用 0 次。before
回调可能会在同一个 promise 进行了许多继续的情况下被多次调用。
¥The before
callback will be called 0 to N times. The before
callback
will typically be called 0 times if no continuation was ever made for the
promise. The before
callback may be called many times in the case where
many continuations have been made from the same promise.
after(promise)
#
promise
<Promise>
在 promise 继续执行后立即调用。这可能在 then()
、catch()
或 finally()
句柄之后,或者在另一个 await
之后的 await
之前。
¥Called immediately after a promise continuation executes. This may be after a
then()
, catch()
, or finally()
handler or before an await
after another
await
.
settled(promise)
#
promise
<Promise>
当 promise 收到解决或拒绝值时调用。这可能在 Promise.resolve()
或 Promise.reject()
的情况下同步地发生。
¥Called when the promise receives a resolution or rejection value. This may
occur synchronously in the case of Promise.resolve()
or Promise.reject()
.
启动快照 API#
¥Startup Snapshot API
¥Stability: 1 - Experimental
v8.startupSnapshot
接口可用于为自定义启动快照添加序列化和反序列化钩子。目前启动快照只能从源代码构建到 Node.js 二进制文件中。
¥The v8.startupSnapshot
interface can be used to add serialization and
deserialization hooks for custom startup snapshots. Currently the startup
snapshots can only be built into the Node.js binary from source.
$ cd /path/to/node
$ ./configure --node-snapshot-main=entry.js
$ make node
# This binary contains the result of the execution of entry.js
$ out/Release/node
在上面的例子中,entry.js
可以使用来自 v8.startupSnapshot
接口的方法来指定如何在序列化过程中为快照中的自定义对象保存信息,以及如何在快照的反序列化过程中使用这些信息来同步这些对象。例如,如果 entry.js
包含以下脚本:
¥In the example above, entry.js
can use methods from the v8.startupSnapshot
interface to specify how to save information for custom objects in the snapshot
during serialization and how the information can be used to synchronize these
objects during deserialization of the snapshot. For example, if the entry.js
contains the following script:
'use strict';
const fs = require('fs');
const zlib = require('zlib');
const path = require('path');
const assert = require('assert');
const {
isBuildingSnapshot,
addSerializeCallback,
addDeserializeCallback,
setDeserializeMainFunction
} = require('v8').startupSnapshot;
const filePath = path.resolve(__dirname, '../x1024.txt');
const storage = {};
assert(isBuildingSnapshot());
addSerializeCallback(({ filePath }) => {
storage[filePath] = zlib.gzipSync(fs.readFileSync(filePath));
}, { filePath });
addDeserializeCallback(({ filePath }) => {
storage[filePath] = zlib.gunzipSync(storage[filePath]);
}, { filePath });
setDeserializeMainFunction(({ filePath }) => {
console.log(storage[filePath].toString());
}, { filePath });
生成的二进制文件将在启动期间简单地打印从快照反序列化的数据:
¥The resulted binary will simply print the data deserialized from the snapshot during start up:
$ out/Release/node
# Prints content of ./test/fixtures/x1024.txt
目前该 API 仅适用于从默认快照启动的 Node.js 实例,即从用户端快照反序列化的应用无法再次使用这些 API。
¥Currently the API is only available to a Node.js instance launched from the default snapshot, that is, the application deserialized from a user-land snapshot cannot use these APIs again.
v8.startupSnapshot.addSerializeCallback(callback[, data])
#
-
callback
<Function> 在序列化之前调用的回调。¥
callback
<Function> Callback to be invoked before serialization. -
data
<any> 调用时将传给callback
的可选数据。¥
data
<any> Optional data that will be passed to thecallback
when it gets called.
添加一个回调,当 Node.js 实例即将序列化为快照并退出时将调用该回调。这可以用来释放不应该或者不能序列化的资源或者将用户数据转换成更适合序列化的形式。
¥Add a callback that will be called when the Node.js instance is about to get serialized into a snapshot and exit. This can be used to release resources that should not or cannot be serialized or to convert user data into a form more suitable for serialization.
v8.startupSnapshot.addDeserializeCallback(callback[, data])
#
-
callback
<Function> 快照反序列化后调用的回调。¥
callback
<Function> Callback to be invoked after the snapshot is deserialized. -
data
<any> 调用时将传给callback
的可选数据。¥
data
<any> Optional data that will be passed to thecallback
when it gets called.
添加从快照反序列化 Node.js 实例时将调用的回调。callback
和 data
(如果提供)将被序列化到快照中,它们可用于重新初始化应用的状态,或者在应用从快照重新启动时重新获取应用所需的资源。
¥Add a callback that will be called when the Node.js instance is deserialized
from a snapshot. The callback
and the data
(if provided) will be
serialized into the snapshot, they can be used to re-initialize the state
of the application or to re-acquire resources that the application needs
when the application is restarted from the snapshot.
v8.startupSnapshot.setDeserializeMainFunction(callback[, data])
#
-
callback
<Function> 快照反序列化后作为入口点调用的回调。¥
callback
<Function> Callback to be invoked as the entry point after the snapshot is deserialized. -
data
<any> 调用时将传给callback
的可选数据。¥
data
<any> Optional data that will be passed to thecallback
when it gets called.
这设置了从快照反序列化 Node.js 应用的入口点。在快照构建脚本中只能调用一次。如果被调用,反序列化应用不再需要额外的入口点脚本来启动,并且只需调用回调以及反序列化数据(如果提供),否则仍需要向反序列化应用提供入口点脚本。
¥This sets the entry point of the Node.js application when it is deserialized from a snapshot. This can be called only once in the snapshot building script. If called, the deserialized application no longer needs an additional entry point script to start up and will simply invoke the callback along with the deserialized data (if provided), otherwise an entry point script still needs to be provided to the deserialized application.
v8.startupSnapshot.isBuildingSnapshot()
#
如果运行 Node.js 实例来构建快照,则返回 true。
¥Returns true if the Node.js instance is run to build a snapshot.