Node.js v20.11.1 文档


Node-API#

稳定性: 2 - 稳定的

Stability: 2 - Stable

Node-API(以前称为 N-API)是用于构建原生插件的 API。它独立于底层 JavaScript 运行时(例如 V8),并作为 Node.js 本身的一部分进行维护。此 API 将在 Node.js 的各个版本中保持稳定的应用二进制接口 (ABI)。它旨在将插件与底层 JavaScript 引擎的变化隔离开来,并允许为一个主要版本编译的模块无需重新编译即可在以后的 Node.js 主要版本上运行。ABI 稳定性 指南提供了更深入的解释。

Node-API (formerly N-API) is an API for building native Addons. It is independent from the underlying JavaScript runtime (for example, V8) and is maintained as part of Node.js itself. This API will be Application Binary Interface (ABI) stable across versions of Node.js. It is intended to insulate addons from changes in the underlying JavaScript engine and allow modules compiled for one major version to run on later major versions of Node.js without recompilation. The ABI Stability guide provides a more in-depth explanation.

插件是使用标头为 C++ 插件 的部分中概述的相同方法/工具构建/打包的。唯一的区别是原生代码使用的 API 集。不使用 V8 或 Node.js 的原生抽象 API,而是使用 Node-API 中可用的函数。

Addons are built/packaged with the same approach/tools outlined in the section titled C++ Addons. The only difference is the set of APIs that are used by the native code. Instead of using the V8 or Native Abstractions for Node.js APIs, the functions available in Node-API are used.

Node-API 公开的 API 通常用于创建和操作 JavaScript 值。概念和操作通常映射到 ECMA-262 语言规范中指定的想法。API 具有以下属性:

APIs exposed by Node-API are generally used to create and manipulate JavaScript values. Concepts and operations generally map to ideas specified in the ECMA-262 Language Specification. The APIs have the following properties:

  • 所有 Node-API 调用都会返回 napi_status 类型的状态代码。此状态指示 API 调用是成功还是失败。

    All Node-API calls return a status code of type napi_status. This status indicates whether the API call succeeded or failed.

  • API 的返回值通过 out 参数传递。

    The API's return value is passed via an out parameter.

  • 所有 JavaScript 值都被抽象为一个名为 napi_value 的不透明类型。

    All JavaScript values are abstracted behind an opaque type named napi_value.

  • 如果出现错误状态代码,可以使用 napi_get_last_error_info 获取附加信息。可以在错误处理部分 错误处理 中找到更多信息。

    In case of an error status code, additional information can be obtained using napi_get_last_error_info. More information can be found in the error handling section Error handling.

Node-API 是一种 C API,可确保跨 Node.js 版本和不同编译器级别的 ABI 稳定性。C++ API 可以更容易使用。为了支持使用 C++,该项目维护了一个名为 node-addon-api 的 C++ 封装器模块。这个封装器提供了一个可内联的 C++ API。使用 node-addon-api 构建的二进制文件将取决于 Node.js 导出的基于 Node-API C 的函数的符号。node-addon-api 是编写调用 Node-API 的代码的更有效方式。举个例子,下面的 node-addon-api 代码。第一部分显示 node-addon-api 代码,第二部分显示插件中实际使用的内容。

Node-API is a C API that ensures ABI stability across Node.js versions and different compiler levels. A C++ API can be easier to use. To support using C++, the project maintains a C++ wrapper module called node-addon-api. This wrapper provides an inlinable C++ API. Binaries built with node-addon-api will depend on the symbols for the Node-API C-based functions exported by Node.js. node-addon-api is a more efficient way to write code that calls Node-API. Take, for example, the following node-addon-api code. The first section shows the node-addon-api code and the second section shows what actually gets used in the addon.

Object obj = Object::New(env);
obj["foo"] = String::New(env, "bar"); 
napi_status status;
napi_value object, string;
status = napi_create_object(env, &object);
if (status != napi_ok) {
  napi_throw_error(env, ...);
  return;
}

status = napi_create_string_utf8(env, "bar", NAPI_AUTO_LENGTH, &string);
if (status != napi_ok) {
  napi_throw_error(env, ...);
  return;
}

status = napi_set_named_property(env, object, "foo", string);
if (status != napi_ok) {
  napi_throw_error(env, ...);
  return;
} 

最终结果是该插件仅使用导出的 C API。因此,它仍然可以获得 C API 提供的 ABI 稳定性的好处。

The end result is that the addon only uses the exported C APIs. As a result, it still gets the benefits of the ABI stability provided by the C API.

当使用 node-addon-api 而不是 C API 时,从 node-addon-api 的 API 文档 开始。

When using node-addon-api instead of the C APIs, start with the API docs for node-addon-api.

Node-API 资源 为刚开始使用 Node-API 和 node-addon-api 的开发者提供了很好的指导和技巧。可以在 Node-API 媒体 页面上找到其他媒体资源。

The Node-API Resource offers an excellent orientation and tips for developers just getting started with Node-API and node-addon-api. Additional media resources can be found on the Node-API Media page.

ABI 稳定性的影响#

Implications of ABI stability

尽管 Node-API 提供了 ABI 稳定性保证,但 Node.js 的其他部分却没有,插件中使用的任何外部库也可能没有。特别是,以下 API 均未提供跨主要版本的 ABI 稳定性保证:

Although Node-API provides an ABI stability guarantee, other parts of Node.js do not, and any external libraries used from the addon may not. In particular, none of the following APIs provide an ABI stability guarantee across major versions:

  • 可通过任何方式获得的 Node.js C++ API

    the Node.js C++ APIs available via any of

    #include <node.h>
    #include <node_buffer.h>
    #include <node_version.h>
    #include <node_object_wrap.h> 
  • libuv API,它也包含在 Node.js 中,可通过

    the libuv APIs which are also included with Node.js and available via

    #include <uv.h> 
  • V8 API 可通过

    the V8 API available via

    #include <v8.h> 

因此,为了使插件在 Node.js 主要版本之间保持 ABI 兼容,它必须通过限制自己使用来独占使用 Node-API

Thus, for an addon to remain ABI-compatible across Node.js major versions, it must use Node-API exclusively by restricting itself to using

#include <node_api.h> 

并通过检查它使用的所有外部库,外部库使 ABI 稳定性保证类似于 Node-API。

and by checking, for all external libraries that it uses, that the external library makes ABI stability guarantees similar to Node-API.

构建#

Building

与用 JavaScript 编写的模块不同,使用 Node-API 开发和部署 Node.js 原生插件需要一组额外的工具。除了为 Node.js 开发所需的基本工具外,原生插件开发者还需要一个可以将 C 和 C++ 代码编译为二进制文件的工具链。此外,根据原生插件的部署方式,原生插件的用户还需要安装 C/C++ 工具链。

Unlike modules written in JavaScript, developing and deploying Node.js native addons using Node-API requires an additional set of tools. Besides the basic tools required to develop for Node.js, the native addon developer requires a toolchain that can compile C and C++ code into a binary. In addition, depending upon how the native addon is deployed, the user of the native addon will also need to have a C/C++ toolchain installed.

对于 Linux 开发者,必要的 C/C++ 工具链包很容易获得。GCC 在 Node.js 社区中被广泛用于跨各种平台构建和测试。对于许多开发者来说,LLVM 编译器基础设施也是一个不错的选择。

For Linux developers, the necessary C/C++ toolchain packages are readily available. GCC is widely used in the Node.js community to build and test across a variety of platforms. For many developers, the LLVM compiler infrastructure is also a good choice.

对于 Mac 开发者,Xcode 提供了所有必需的编译器工具。但是,没有必要安装整个 Xcode IDE。以下命令安装必要的工具链:

For Mac developers, Xcode offers all the required compiler tools. However, it is not necessary to install the entire Xcode IDE. The following command installs the necessary toolchain:

xcode-select --install 

对于 Windows 开发者,Visual Studio 提供了所有必需的编译器工具。但是,没有必要安装整个 Visual Studio IDE。以下命令安装必要的工具链:

For Windows developers, Visual Studio offers all the required compiler tools. However, it is not necessary to install the entire Visual Studio IDE. The following command installs the necessary toolchain:

npm install --global windows-build-tools 

以下部分描述了可用于开发和部署 Node.js 原生插件的其他工具。

The sections below describe the additional tools available for developing and deploying Node.js native addons.

构建工具#

Build tools

此处列出的两种工具都要求原生插件的用户安装 C/C++ 工具链才能成功安装原生插件。

Both the tools listed here require that users of the native addon have a C/C++ toolchain installed in order to successfully install the native addon.

node-gyp#

node-gyp 是一个构建系统,基于 Google 的 GYP 工具的 gyp-next 分支,并与 npm 打包在一起。GYP,因此 node-gyp,需要安装 Python。

node-gyp is a build system based on the gyp-next fork of Google's GYP tool and comes bundled with npm. GYP, and therefore node-gyp, requires that Python be installed.

从历史上看,node-gyp 一直是构建原生插件的首选工具。它具有广泛的采用和文档。但是,一些开发者在 node-gyp 中遇到了限制。

Historically, node-gyp has been the tool of choice for building native addons. It has widespread adoption and documentation. However, some developers have run into limitations in node-gyp.

CMake.js#

CMake.js 是基于 CMake 的替代构建系统。

CMake.js is an alternative build system based on CMake.

对于已经使用 CMake 的项目或受 node-gyp 限制影响的开发者,CMake.js 是一个不错的选择。

CMake.js is a good choice for projects that already use CMake or for developers affected by limitations in node-gyp.

上传预编译的二进制文件#

Uploading precompiled binaries

此处列出的三个工具允许本地插件开发者和维护人员创建二进制文件并将其上传到公共或私有服务器。这些工具通常与 Travis CIAppVeyor 等 CI/CD 构建系统集成,为各种平台和架构构建和上传二进制文件。这些二进制文件可供不需要安装 C/C++ 工具链的用户下载。

The three tools listed here permit native addon developers and maintainers to create and upload binaries to public or private servers. These tools are typically integrated with CI/CD build systems like Travis CI and AppVeyor to build and upload binaries for a variety of platforms and architectures. These binaries are then available for download by users who do not need to have a C/C++ toolchain installed.

node-pre-gyp#

node-pre-gyp 是一个基于 node-gyp 的工具,它增加了将二进制文件上传到开发者选择的服务器的能力。node-pre-gyp 对将二进制文件上传到 Amazon S3 有特别好的支持。

node-pre-gyp is a tool based on node-gyp that adds the ability to upload binaries to a server of the developer's choice. node-pre-gyp has particularly good support for uploading binaries to Amazon S3.

prebuild#

prebuild 是一个支持使用 node-gyp 或 CMake.js 构建的工具。与支持多种服务器的 node-pre-gyp 不同,prebuild 仅将二进制文件上传到 GitHub 发布。prebuild 是使用 CMake.js 的 GitHub 项目的不错选择。

prebuild is a tool that supports builds using either node-gyp or CMake.js. Unlike node-pre-gyp which supports a variety of servers, prebuild uploads binaries only to GitHub releases. prebuild is a good choice for GitHub projects using CMake.js.

prebuildify#

prebuildify 是一个基于 node-gyp 的工具。prebuildify 的优点是构建的二进制文件在上传到 npm 时与原生插件打包在一起。二进制文件从 npm 下载,并在安装原生插件时立即可供模块用户使用。

prebuildify is a tool based on node-gyp. The advantage of prebuildify is that the built binaries are bundled with the native addon when it's uploaded to npm. The binaries are downloaded from npm and are immediately available to the module user when the native addon is installed.

使用方法#

Usage

为了使用 Node-API 函数,在节点开发树中包含位于 src 目录中的文件 node_api.h

In order to use the Node-API functions, include the file node_api.h which is located in the src directory in the node development tree:

#include <node_api.h> 

这将为给定的 Node.js 版本选择默认的 NAPI_VERSION。为了确保与特定版本的 Node-API 兼容,可以在包含标头时明确指定版本:

This will opt into the default NAPI_VERSION for the given release of Node.js. In order to ensure compatibility with specific versions of Node-API, the version can be specified explicitly when including the header:

#define NAPI_VERSION 3
#include <node_api.h> 

这将 Node-API 表面限制为仅在指定(和更早)版本中可用的功能。

This restricts the Node-API surface to just the functionality that was available in the specified (and earlier) versions.

一些 Node-API 表面是实验性的,需要明确选择加入:

Some of the Node-API surface is experimental and requires explicit opt-in:

#define NAPI_EXPERIMENTAL
#include <node_api.h> 

在这种情况下,整个 API 表面,包括任何实验性 API,都将可用于模块代码。

In this case the entire API surface, including any experimental APIs, will be available to the module code.

Node-API 版本矩阵#

Node-API version matrix

在版本 9 之前,Node-API 版本是附加的,并且版本独立于 Node.js。这意味着任何版本都是先前版本的扩展,因为它拥有先前版本的所有 API 并添加了一些内容。每个 Node.js 版本仅支持一个 Node-API 版本。例如,v18.15.0 仅支持 Node-API 版本 8。实现 ABI 稳定性是因为 8 是所有以前版本的严格超集。

Up until version 9, Node-API versions were additive and versioned independently from Node.js. This meant that any version was an extension to the previous version in that it had all of the APIs from the previous version with some additions. Each Node.js version only supported a single Node-API version. For example v18.15.0 supports only Node-API version 8. ABI stability was achieved because 8 was a strict superset of all previous versions.

从版本 9 开始,虽然 Node-API 版本继续独立进行版本控制,但与 Node-API 版本 9 一起运行的附加组件可能需要更新代码才能与 Node-API 版本 10 一起运行。然而,ABI 稳定性得以保持,因为支持高于 8 的 Node-API 版本的 Node.js 版本将支持 8 及其支持的最高版本之间的所有版本,并且将默认提供版本 8 API,除非附加组件选择加入 更高的 Node-API 版本。这种方法提供了更好地优化现有 Node-API 功能的灵活性,同时保持 ABI 稳定性。现有的附加组件可以继续运行,无需使用早期版本的 Node-API 重新编译。如果附加组件需要较新 Node-API 版本的功能,则无论如何都需要更改现有代码并重新编译才能使用这些新功能。

As of version 9, while Node-API versions continue to be versioned independently an add-on that ran with Node-API version 9 may need code updates to run with Node-API version 10. ABI stability is maintained, however, because Node.js versions that support Node-API versions higher than 8 will support all versions between 8 and the highest version they support and will default to providing the version 8 APIs unless an add-on opts into a higher Node-API version. This approach provides the flexibility of better optimizing existing Node-API functions while maintaining ABI stability. Existing add-ons can continue to run without recompilation using an earlier version of Node-API. If an add-on needs functionality from a newer Node-API version, changes to existing code and recompilation will be needed to use those new functions anyway.

在支持 Node-API 版本 9 及更高版本的 Node.js 版本中,定义 NAPI_VERSION=X 并使用现有的附加组件初始化宏会将请求的 Node-API 版本烘焙到附加组件中,该版本将在运行时使用。如果未设置 NAPI_VERSION,则默认为 8。

In versions of Node.js that support Node-API version 9 and later, defining NAPI_VERSION=X and using the existing add-on initialization macros will bake in the requested Node-API version that will be used at runtime into the add-on. If NAPI_VERSION is not set it will default to 8.

此表在较旧的流中可能不是最新的,最新的信息位于最新的 API 文档中:Node-API 版本矩阵

This table may not be up to date in older streams, the most up to date information is in the latest API documentation in: Node-API version matrix

Node-API 版本 支持于
9 v18.17.0+、20.3.0+、21.0.0 及所有更高版本
8 v12.22.0+、v14.17.0+、v15.12.0+、16.0.0 及所有更高版本
7 v10.23.0+、v12.19.0+、v14.12.0+、15.0.0 及所有更高版本
6 v10.20.0+、v12.17.0+、14.0.0 及所有更高版本
5 v10.17.0+、v12.11.0+、13.0.0 及所有更高版本
4 v10.16.0+、v11.8.0+、12.0.0 及所有更高版本
3 v6.14.2*、8.11.2+、v9.11.0+*、10.0.0 及所有更高版本
2 v8.10.0+、v9.3.0+、10.0.0 及所有更高版本
1 v8.6.0+**、v9.0.0+*、10.0.0 及所有更高版本
  • Node-API 是实验性的。

* Node-API was experimental.

** Node.js 8.0.0 包含 Node-API 作为实验性的。它作为 Node-API 版本 1 发布,但继续改进直到 Node.js 8.6.0。API 在 Node.js 8.6.0 之前的版本中有所不同。我们推荐 Node-API 版本 3 或更高版本。

** Node.js 8.0.0 included Node-API as experimental. It was released as Node-API version 1 but continued to evolve until Node.js 8.6.0. The API is different in versions prior to Node.js 8.6.0. We recommend Node-API version 3 or later.

为 Node-API 记录的每个 API 都有一个名为 added in: 的标头,而稳定的 API 将有一个额外的标头 Node-API version:。当使用支持 Node-API version: 或更高版本中所示的 Node-API 版本的 Node.js 版本时,API 可直接使用。当使用不支持列出的 Node-API version: 的 Node.js 版本时,或者如果没有列出 Node-API version:,则只有在包含 node_api.hjs_native_api.h 之前包含 #define NAPI_EXPERIMENTAL 时,API 才可用。如果某个 API 在晚于 added in: 中所示版本的 Node.js 版本上似乎不可用,那么这很可能是明显缺失的原因。

Each API documented for Node-API will have a header named added in:, and APIs which are stable will have the additional header Node-API version:. APIs are directly usable when using a Node.js version which supports the Node-API version shown in Node-API version: or higher. When using a Node.js version that does not support the Node-API version: listed or if there is no Node-API version: listed, then the API will only be available if #define NAPI_EXPERIMENTAL precedes the inclusion of node_api.h or js_native_api.h. If an API appears not to be available on a version of Node.js which is later than the one shown in added in: then this is most likely the reason for the apparent absence.

与从原生代码访问 ECMAScript 功能严格相关的 Node-API 可以在 js_native_api.hjs_native_api_types.h 中单独找到。这些标头中定义的 API 包含在 node_api.hnode_api_types.h 中。标头以这种方式构造,以便允许在 Node.js 之外实现 Node-API。对于这些实现,Node.js 特定的 API 可能不适用。

The Node-APIs associated strictly with accessing ECMAScript features from native code can be found separately in js_native_api.h and js_native_api_types.h. The APIs defined in these headers are included in node_api.h and node_api_types.h. The headers are structured in this way in order to allow implementations of Node-API outside of Node.js. For those implementations the Node.js specific APIs may not be applicable.

插件的 Node.js 特定部分可以与将实际功能暴露给 JavaScript 环境的代码分开,以便后者可以与 Node-API 的多个实现一起使用。在下面的示例中,addon.caddon.h 仅引用 js_native_api.h。这确保了 addon.c 可以被重用以针对 Node-API 的 Node.js 实现或 Node.js 之外的任何 Node-API 实现进行编译。

The Node.js-specific parts of an addon can be separated from the code that exposes the actual functionality to the JavaScript environment so that the latter may be used with multiple implementations of Node-API. In the example below, addon.c and addon.h refer only to js_native_api.h. This ensures that addon.c can be reused to compile against either the Node.js implementation of Node-API or any implementation of Node-API outside of Node.js.

addon_node.c 是一个单独的文件,其中包含插件的 Node.js 特定入口点,并在插件加载到 Node.js 环境时通过调用 addon.c 来实例化插件。

addon_node.c is a separate file that contains the Node.js specific entry point to the addon and which instantiates the addon by calling into addon.c when the addon is loaded into a Node.js environment.

// addon.h
#ifndef _ADDON_H_
#define _ADDON_H_
#include <js_native_api.h>
napi_value create_addon(napi_env env);
#endif  // _ADDON_H_ 
// addon.c
#include "addon.h"

#define NODE_API_CALL(env, call)                                  \
  do {                                                            \
    napi_status status = (call);                                  \
    if (status != napi_ok) {                                      \
      const napi_extended_error_info* error_info = NULL;          \
      napi_get_last_error_info((env), &error_info);               \
      const char* err_message = error_info->error_message;        \
      bool is_pending;                                            \
      napi_is_exception_pending((env), &is_pending);              \
      /* If an exception is already pending, don't rethrow it */  \
      if (!is_pending) {                                          \
        const char* message = (err_message == NULL)               \
            ? "empty error message"                               \
            : err_message;                                        \
        napi_throw_error((env), NULL, message);                   \
      }                                                           \
      return NULL;                                                \
    }                                                             \
  } while(0)

static napi_value
DoSomethingUseful(napi_env env, napi_callback_info info) {
  // Do something useful.
  return NULL;
}

napi_value create_addon(napi_env env) {
  napi_value result;
  NODE_API_CALL(env, napi_create_object(env, &result));

  napi_value exported_function;
  NODE_API_CALL(env, napi_create_function(env,
                                          "doSomethingUseful",
                                          NAPI_AUTO_LENGTH,
                                          DoSomethingUseful,
                                          NULL,
                                          &exported_function));

  NODE_API_CALL(env, napi_set_named_property(env,
                                             result,
                                             "doSomethingUseful",
                                             exported_function));

  return result;
} 
// addon_node.c
#include <node_api.h>
#include "addon.h"

NAPI_MODULE_INIT() {
  // This function body is expected to return a `napi_value`.
  // The variables `napi_env env` and `napi_value exports` may be used within
  // the body, as they are provided by the definition of `NAPI_MODULE_INIT()`.
  return create_addon(env);
} 

环境生命周期 API#

Environment life cycle APIs

ECMAScript 语言规范第 8.7 节 将 "代理" 的概念定义为运行 JavaScript 代码的独立环境。进程可以同时或按顺序启动和终止多个此类代理。

Section 8.7 of the ECMAScript Language Specification defines the concept of an "Agent" as a self-contained environment in which JavaScript code runs. Multiple such Agents may be started and terminated either concurrently or in sequence by the process.

一个 Node.js 环境对应一个 ECMAScript Agent。在主进程中,启动时创建一个环境,可以在单独的线程上创建额外的环境作为 工作线程。当 Node.js 嵌入到另一个应用中时,应用的主线程也可能在应用的生命周期中多次构造和销毁 Node.js 环境,使得应用创建的每个 Node.js 环境可能,在 反过来,在其生命周期中创建和销毁额外的环境作为工作线程。

A Node.js environment corresponds to an ECMAScript Agent. In the main process, an environment is created at startup, and additional environments can be created on separate threads to serve as worker threads. When Node.js is embedded in another application, the main thread of the application may also construct and destroy a Node.js environment multiple times during the life cycle of the application process such that each Node.js environment created by the application may, in turn, during its life cycle create and destroy additional environments as worker threads.

从原生插件的角度来看,这意味着它提供的绑定可以从多个上下文中多次调用,甚至可以同时从多个线程中调用。

From the perspective of a native addon this means that the bindings it provides may be called multiple times, from multiple contexts, and even concurrently from multiple threads.

原生插件可能需要分配它们在 Node.js 环境的生命周期中使用的全局状态,以便该状态对于插件的每个实例都是唯一的。

Native addons may need to allocate global state which they use during their life cycle of an Node.js environment such that the state can be unique to each instance of the addon.

为此,Node-API 提供了一种关联数据的方法,使其生命周期与 Node.js 环境的生命周期相关联。

To this end, Node-API provides a way to associate data such that its life cycle is tied to the life cycle of a Node.js environment.

napi_set_instance_data#

napi_status napi_set_instance_data(napi_env env,
                                   void* data,
                                   napi_finalize finalize_cb,
                                   void* finalize_hint); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] data:可用于此实例的绑定的数据项。

    [in] data: The data item to make available to bindings of this instance.

  • [in] finalize_cb:拆除环境时调用的函数。该函数接收 data 以便释放它。napi_finalize 提供了更多详细信息。

    [in] finalize_cb: The function to call when the environment is being torn down. The function receives data so that it might free it. napi_finalize provides more details.

  • [in] finalize_hint:在收集期间传递给最终回调的可选提示。

    [in] finalize_hint: Optional hint to pass to the finalize callback during collection.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 将 data 与当前运行的 Node.js 环境相关联。稍后可以使用 napi_get_instance_data() 检索 data。通过先前调用 napi_set_instance_data() 设置的与当前运行的 Node.js 环境关联的任何现有数据都将被覆盖。如果之前调用提供了 finalize_cb,则不会调用它。

This API associates data with the currently running Node.js environment. data can later be retrieved using napi_get_instance_data(). Any existing data associated with the currently running Node.js environment which was set by means of a previous call to napi_set_instance_data() will be overwritten. If a finalize_cb was provided by the previous call, it will not be called.

napi_get_instance_data#

napi_status napi_get_instance_data(napi_env env,
                                   void** data); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [out] data:之前通过调用 napi_set_instance_data() 与当前运行的 Node.js 环境相关联的数据项。

    [out] data: The data item that was previously associated with the currently running Node.js environment by a call to napi_set_instance_data().

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 检索以前通过 napi_set_instance_data() 与当前运行的 Node.js 环境关联的数据。如果没有设置数据,则调用成功,data 将设置为 NULL

This API retrieves data that was previously associated with the currently running Node.js environment via napi_set_instance_data(). If no data is set, the call will succeed and data will be set to NULL.

基本的 Node-API 数据类型#

Basic Node-API data types

Node-API 将以下基本数据类型公开为各种 API 使用的抽象。这些 API 应该被视为不透明的,只能通过其他 Node-API 调用进行自省。

Node-API exposes the following fundamental data types as abstractions that are consumed by the various APIs. These APIs should be treated as opaque, introspectable only with other Node-API calls.

napi_status#

指示 Node-API 调用成功或失败的完整状态代码。目前支持以下状态码。

Integral status code indicating the success or failure of a Node-API call. Currently, the following status codes are supported.

typedef enum {
  napi_ok,
  napi_invalid_arg,
  napi_object_expected,
  napi_string_expected,
  napi_name_expected,
  napi_function_expected,
  napi_number_expected,
  napi_boolean_expected,
  napi_array_expected,
  napi_generic_failure,
  napi_pending_exception,
  napi_cancelled,
  napi_escape_called_twice,
  napi_handle_scope_mismatch,
  napi_callback_scope_mismatch,
  napi_queue_full,
  napi_closing,
  napi_bigint_expected,
  napi_date_expected,
  napi_arraybuffer_expected,
  napi_detachable_arraybuffer_expected,
  napi_would_deadlock,  /* unused */
  napi_no_external_buffers_allowed,
  napi_cannot_run_js
} napi_status; 

如果 API 返回失败状态时需要额外的信息,可以通过调用 napi_get_last_error_info 获取。

If additional information is required upon an API returning a failed status, it can be obtained by calling napi_get_last_error_info.

napi_extended_error_info#

typedef struct {
  const char* error_message;
  void* engine_reserved;
  uint32_t engine_error_code;
  napi_status error_code;
} napi_extended_error_info; 
  • error_message:UTF8 编码的字符串,包含错误的 VM 中立描述。

    error_message: UTF8-encoded string containing a VM-neutral description of the error.

  • engine_reserved:为特定于 VM 的错误详细信息保留。目前尚未为任何 VM 实现此功能。

    engine_reserved: Reserved for VM-specific error details. This is currently not implemented for any VM.

  • engine_error_code:特定于 VM 的错误代码。目前尚未为任何 VM 实现此功能。

    engine_error_code: VM-specific error code. This is currently not implemented for any VM.

  • error_code:源自最后一个错误的 Node-API 状态代码。

    error_code: The Node-API status code that originated with the last error.

有关其他信息,请参阅 错误处理 部分。

See the Error handling section for additional information.

napi_env#

napi_env 用于表示底层 Node-API 实现可用于持久化 VM 特定状态的上下文。此结构在调用时传递给原生函数,并且在进行 Node-API 调用时必须传回。具体来说,调用初始原生函数时传入的相同 napi_env 必须传递给任何后续的嵌套 Node-API 调用。出于一般重用的目的缓存 napi_env,以及在不同 Worker 线程上运行的同一插件的实例之间传递 napi_env 是不允许的。当卸载原生插件的实例时,napi_env 变得无效。此事件的通知通过给 napi_add_env_cleanup_hooknapi_set_instance_data 的回调传递。

napi_env is used to represent a context that the underlying Node-API implementation can use to persist VM-specific state. This structure is passed to native functions when they're invoked, and it must be passed back when making Node-API calls. Specifically, the same napi_env that was passed in when the initial native function was called must be passed to any subsequent nested Node-API calls. Caching the napi_env for the purpose of general reuse, and passing the napi_env between instances of the same addon running on different Worker threads is not allowed. The napi_env becomes invalid when an instance of a native addon is unloaded. Notification of this event is delivered through the callbacks given to napi_add_env_cleanup_hook and napi_set_instance_data.

napi_value#

这是一个用于表示 JavaScript 值的不透明指针。

This is an opaque pointer that is used to represent a JavaScript value.

napi_threadsafe_function#

这是一个不透明的指针,表示可以通过 napi_call_threadsafe_function() 从多个线程异步调用的 JavaScript 函数。

This is an opaque pointer that represents a JavaScript function which can be called asynchronously from multiple threads via napi_call_threadsafe_function().

napi_threadsafe_function_release_mode#

赋予 napi_release_threadsafe_function() 的值指示线程安全函数是立即关闭 (napi_tsfn_abort) 还是仅释放 (napi_tsfn_release) 并因此可通过 napi_acquire_threadsafe_function()napi_call_threadsafe_function() 进行后续使用。

A value to be given to napi_release_threadsafe_function() to indicate whether the thread-safe function is to be closed immediately (napi_tsfn_abort) or merely released (napi_tsfn_release) and thus available for subsequent use via napi_acquire_threadsafe_function() and napi_call_threadsafe_function().

typedef enum {
  napi_tsfn_release,
  napi_tsfn_abort
} napi_threadsafe_function_release_mode; 

napi_threadsafe_function_call_mode#

赋予 napi_call_threadsafe_function() 的值,以指示只要与线程安全函数关联的队列已满,调用是否应阻塞。

A value to be given to napi_call_threadsafe_function() to indicate whether the call should block whenever the queue associated with the thread-safe function is full.

typedef enum {
  napi_tsfn_nonblocking,
  napi_tsfn_blocking
} napi_threadsafe_function_call_mode; 

Node-API 内存管理类型#

Node-API memory management types

napi_handle_scope#

这是一种抽象,用于控制和修改在特定范围内创建的对象的生命周期。通常,Node-API 值是在句柄范围的上下文中创建的。当从 JavaScript 调用原生方法时,将存在默认句柄范围。如果用户没有显式创建新的句柄范围,Node-API 值将在默认句柄范围内创建。对于原生方法执行之外的任何代码调用(例如,在 libuv 回调调用期间),模块需要在调用任何可能导致创建 JavaScript 值的函数之前创建范围。

This is an abstraction used to control and modify the lifetime of objects created within a particular scope. In general, Node-API values are created within the context of a handle scope. When a native method is called from JavaScript, a default handle scope will exist. If the user does not explicitly create a new handle scope, Node-API values will be created in the default handle scope. For any invocations of code outside the execution of a native method (for instance, during a libuv callback invocation), the module is required to create a scope before invoking any functions that can result in the creation of JavaScript values.

句柄作用域使用 napi_open_handle_scope 创建,使用 napi_close_handle_scope 销毁。关闭作用域可以向 GC 表明在句柄作用域的生命周期内创建的所有 napi_value 不再从当前堆栈帧中引用。

Handle scopes are created using napi_open_handle_scope and are destroyed using napi_close_handle_scope. Closing the scope can indicate to the GC that all napi_values created during the lifetime of the handle scope are no longer referenced from the current stack frame.

有关详细信息,请查看 对象生命周期管理

For more details, review the Object lifetime management.

napi_escapable_handle_scope#

可转义句柄范围是一种特殊类型的句柄范围,用于将在特定句柄范围内创建的值返回到父范围。

Escapable handle scopes are a special type of handle scope to return values created within a particular handle scope to a parent scope.

napi_ref#

这是用于引用 napi_value 的抽象。这允许用户管理 JavaScript 值的生命周期,包括明确定义它们的最小生命周期。

This is the abstraction to use to reference a napi_value. This allows for users to manage the lifetimes of JavaScript values, including defining their minimum lifetimes explicitly.

有关详细信息,请查看 对象生命周期管理

For more details, review the Object lifetime management.

napi_type_tag#

存储为两个无符号 64 位整数的 128 位值。它作为一个 UUID,JavaScript 对象或 外部的 可以是 "tagged",以确保它们属于某种类型。这是比 napi_instanceof 更强的检查,因为如果对象的原型被操纵,后者会报告误报。类型标记与 napi_wrap 一起使用时最有用,因为它确保从封装对象中检索的指针可以安全地转换为与先前应用于 JavaScript 对象的类型标记相对应的原生类型。

A 128-bit value stored as two unsigned 64-bit integers. It serves as a UUID with which JavaScript objects or externals can be "tagged" in order to ensure that they are of a certain type. This is a stronger check than napi_instanceof, because the latter can report a false positive if the object's prototype has been manipulated. Type-tagging is most useful in conjunction with napi_wrap because it ensures that the pointer retrieved from a wrapped object can be safely cast to the native type corresponding to the type tag that had been previously applied to the JavaScript object.

typedef struct {
  uint64_t lower;
  uint64_t upper;
} napi_type_tag; 

napi_async_cleanup_hook_handle#

napi_add_async_cleanup_hook 返回的不透明值。当异步清理事件链完成时,它必须传递给 napi_remove_async_cleanup_hook

An opaque value returned by napi_add_async_cleanup_hook. It must be passed to napi_remove_async_cleanup_hook when the chain of asynchronous cleanup events completes.

Node-API 回调类型#

Node-API callback types

napi_callback_info#

传递给回调函数的不透明数据类型。它可用于获取有关调用回调的上下文的附加信息。

Opaque datatype that is passed to a callback function. It can be used for getting additional information about the context in which the callback was invoked.

napi_callback#

用户提供的原生函数的函数指针类型,这些函数将通过 Node-API 公开给 JavaScript。回调函数应满足以下签名:

Function pointer type for user-provided native functions which are to be exposed to JavaScript via Node-API. Callback functions should satisfy the following signature:

typedef napi_value (*napi_callback)(napi_env, napi_callback_info); 

除非出于 对象生命周期管理 中讨论的原因,否则无需在 napi_callback 中创建句柄和/或回调范围。

Unless for reasons discussed in Object Lifetime Management, creating a handle and/or callback scope inside a napi_callback is not necessary.

napi_finalize#

附加提供的函数的函数指针类型,允许用户在外部拥有的数据准备好清理时收到通知,因为与其关联的对象已被垃圾收集。用户必须提供满足以下签名的函数,该函数将在对象的集合上调用。目前,napi_finalize 可用于查明何时收集具有外部数据的对象。

Function pointer type for add-on provided functions that allow the user to be notified when externally-owned data is ready to be cleaned up because the object with which it was associated with has been garbage-collected. The user must provide a function satisfying the following signature which would get called upon the object's collection. Currently, napi_finalize can be used for finding out when objects that have external data are collected.

typedef void (*napi_finalize)(napi_env env,
                              void* finalize_data,
                              void* finalize_hint); 

除非出于 对象生命周期管理 中讨论的原因,否则无需在函数体内创建句柄和/或回调范围。

Unless for reasons discussed in Object Lifetime Management, creating a handle and/or callback scope inside the function body is not necessary.

由于这些函数可能会在 JavaScript 引擎处于无法执行 JavaScript 代码的状态时被调用,因此即使没有异常挂起,某些 Node-API 调用也可能返回 napi_pending_exception

Since these functions may be called while the JavaScript engine is in a state where it cannot execute JavaScript code, some Node-API calls may return napi_pending_exception even when there is no exception pending.

对于 node_api_create_external_string_latin1node_api_create_external_string_utf16env 参数可以为空,因为在环境关闭的后期可以收集外部字符串。

In the case of node_api_create_external_string_latin1 and node_api_create_external_string_utf16 the env parameter may be null, because external strings can be collected during the latter part of environment shutdown.

变更历史:

Change History:

  • 实验性的(定义了 NAPI_EXPERIMENTAL):

    experimental (NAPI_EXPERIMENTAL is defined):

    当 JavaScript 引擎无法执行 JavaScript 时,从终结器触发的 Node-API 调用将返回 napi_cannot_run_js,如果存在挂起的异常,将返回 napi_exception_pending

    Node-API calls made from a finalizer will return napi_cannot_run_js when the JavaScript engine is unable to execute JavaScript, and will return napi_exception_pending if there is a pending exception.

napi_async_execute_callback#

与支持异步操作的函数一起使用的函数指针。回调函数必须满足以下签名:

Function pointer used with functions that support asynchronous operations. Callback functions must satisfy the following signature:

typedef void (*napi_async_execute_callback)(napi_env env, void* data); 

此函数的实现必须避免进行执行 JavaScript 或与 JavaScript 对象交互的 Node-API 调用。Node-API 调用应该在 napi_async_complete_callback 中。不要使用 napi_env 参数,因为它可能会导致 JavaScript 的执行。

Implementations of this function must avoid making Node-API calls that execute JavaScript or interact with JavaScript objects. Node-API calls should be in the napi_async_complete_callback instead. Do not use the napi_env parameter as it will likely result in execution of JavaScript.

napi_async_complete_callback#

与支持异步操作的函数一起使用的函数指针。回调函数必须满足以下签名:

Function pointer used with functions that support asynchronous operations. Callback functions must satisfy the following signature:

typedef void (*napi_async_complete_callback)(napi_env env,
                                             napi_status status,
                                             void* data); 

除非出于 对象生命周期管理 中讨论的原因,否则无需在函数体内创建句柄和/或回调范围。

Unless for reasons discussed in Object Lifetime Management, creating a handle and/or callback scope inside the function body is not necessary.

napi_threadsafe_function_call_js#

与异步线程安全函数调用一起使用的函数指针。回调将在主线程上调用。它的目的是使用从一个辅助线程通过队列到达的数据项来构造调用 JavaScript 所需的参数,通常是通过 napi_call_function,然后调用 JavaScript。

Function pointer used with asynchronous thread-safe function calls. The callback will be called on the main thread. Its purpose is to use a data item arriving via the queue from one of the secondary threads to construct the parameters necessary for a call into JavaScript, usually via napi_call_function, and then make the call into JavaScript.

通过队列从辅助线程到达的数据在 data 参数中给出,要调用的 JavaScript 函数在 js_callback 参数中给出。

The data arriving from the secondary thread via the queue is given in the data parameter and the JavaScript function to call is given in the js_callback parameter.

Node-API 在调用此回调之前设置环境,因此通过 napi_call_function 而不是通过 napi_make_callback 调用 JavaScript 函数就足够了。

Node-API sets up the environment prior to calling this callback, so it is sufficient to call the JavaScript function via napi_call_function rather than via napi_make_callback.

回调函数必须满足以下签名:

Callback functions must satisfy the following signature:

typedef void (*napi_threadsafe_function_call_js)(napi_env env,
                                                 napi_value js_callback,
                                                 void* context,
                                                 void* data); 
  • [in] env:用于 API 调用的环境,或者 NULL,如果线程安全函数正在被拆除并且 data 可能需要被释放。

    [in] env: The environment to use for API calls, or NULL if the thread-safe function is being torn down and data may need to be freed.

  • [in] js_callback:要调用的 JavaScript 函数,或者 NULL,如果线程安全函数正在被拆除并且 data 可能需要被释放。如果线程安全函数是在没有 js_callback 的情况下创建的,它也可能是 NULL

    [in] js_callback: The JavaScript function to call, or NULL if the thread-safe function is being torn down and data may need to be freed. It may also be NULL if the thread-safe function was created without js_callback.

  • [in] context:用于创建线程安全函数的可选数据。

    [in] context: The optional data with which the thread-safe function was created.

  • [in] data:由辅助线程创建的数据。回调负责将此原生数据转换为 JavaScript 值(使用 Node-API 函数),这些值可以在调用 js_callback 时作为参数传递。这个指针完全由线程和这个回调管理。因此这个回调应该释放数据。

    [in] data: Data created by the secondary thread. It is the responsibility of the callback to convert this native data to JavaScript values (with Node-API functions) that can be passed as parameters when js_callback is invoked. This pointer is managed entirely by the threads and this callback. Thus this callback should free the data.

除非出于 对象生命周期管理 中讨论的原因,否则无需在函数体内创建句柄和/或回调范围。

Unless for reasons discussed in Object Lifetime Management, creating a handle and/or callback scope inside the function body is not necessary.

napi_cleanup_hook#

napi_add_env_cleanup_hook 一起使用的函数指针。当环境被拆除时,它将被调用。

Function pointer used with napi_add_env_cleanup_hook. It will be called when the environment is being torn down.

回调函数必须满足以下签名:

Callback functions must satisfy the following signature:

typedef void (*napi_cleanup_hook)(void* data); 

napi_async_cleanup_hook#

napi_add_async_cleanup_hook 一起使用的函数指针。当环境被拆除时,它将被调用。

Function pointer used with napi_add_async_cleanup_hook. It will be called when the environment is being torn down.

回调函数必须满足以下签名:

Callback functions must satisfy the following signature:

typedef void (*napi_async_cleanup_hook)(napi_async_cleanup_hook_handle handle,
                                        void* data); 

函数体应启动异步清理操作,在清理操作结束时必须在调用 napi_remove_async_cleanup_hook 时传递 handle

The body of the function should initiate the asynchronous cleanup actions at the end of which handle must be passed in a call to napi_remove_async_cleanup_hook.

错误处理#

Error handling

Node-API 使用返回值和 JavaScript 异常来处理错误。以下部分解释了每种情况的方法。

Node-API uses both return values and JavaScript exceptions for error handling. The following sections explain the approach for each case.

返回值#

Return values

所有 Node-API 函数共享相同的错误处理模式。所有 API 函数的返回类型都是 napi_status

All of the Node-API functions share the same error handling pattern. The return type of all API functions is napi_status.

如果请求成功并且没有抛出未捕获的 JavaScript 异常,则返回值将为 napi_ok。如果发生错误并且抛出异常,则将返回错误的 napi_status 值。如果抛出异常且未发生错误,则返回 napi_pending_exception

The return value will be napi_ok if the request was successful and no uncaught JavaScript exception was thrown. If an error occurred AND an exception was thrown, the napi_status value for the error will be returned. If an exception was thrown, and no error occurred, napi_pending_exception will be returned.

在返回 napi_oknapi_pending_exception 以外的返回值的情况下,必须调用 napi_is_exception_pending 来检查是否有异常挂起。有关更多详细信息,请参阅异常部分。

In cases where a return value other than napi_ok or napi_pending_exception is returned, napi_is_exception_pending must be called to check if an exception is pending. See the section on exceptions for more details.

napi_api_types.h 中定义了整套可能的 napi_status 值。

The full set of possible napi_status values is defined in napi_api_types.h.

napi_status 返回值提供了所发生错误的独立于 VM 的表示。在某些情况下,能够获得更详细的信息很有用,包括表示错误的字符串以及特定于 VM(引擎)的信息。

The napi_status return value provides a VM-independent representation of the error which occurred. In some cases it is useful to be able to get more detailed information, including a string representing the error as well as VM (engine)-specific information.

为了检索此信息,提供了 napi_get_last_error_info,它返回 napi_extended_error_info 结构。napi_extended_error_info 结构体的格式如下:

In order to retrieve this information napi_get_last_error_info is provided which returns a napi_extended_error_info structure. The format of the napi_extended_error_info structure is as follows:

typedef struct napi_extended_error_info {
  const char* error_message;
  void* engine_reserved;
  uint32_t engine_error_code;
  napi_status error_code;
}; 
  • error_message:所发生错误的文本表示。

    error_message: Textual representation of the error that occurred.

  • engine_reserved:不透明句柄仅供引擎使用。

    engine_reserved: Opaque handle reserved for engine use only.

  • engine_error_code:VM 特定的错误代码。

    engine_error_code: VM specific error code.

  • error_code:最后一个错误的节点 API 状态代码。

    error_code: Node-API status code for the last error.

napi_get_last_error_info 返回最后一次调用 Node-API 的信息。

napi_get_last_error_info returns the information for the last Node-API call that was made.

不要依赖任何扩展信息的内容或格式,因为它不受 SemVer 的约束并且可能随时更改。它仅用于记录目的。

Do not rely on the content or format of any of the extended information as it is not subject to SemVer and may change at any time. It is intended only for logging purposes.

napi_get_last_error_info#
napi_status
napi_get_last_error_info(napi_env env,
                         const napi_extended_error_info** result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [out] result:包含有关错误的更多信息的 napi_extended_error_info 结构。

    [out] result: The napi_extended_error_info structure with more information about the error.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 检索 napi_extended_error_info 结构,其中包含有关发生的最后一个错误的信息。

This API retrieves a napi_extended_error_info structure with information about the last error that occurred.

返回的 napi_extended_error_info 的内容仅在对同一 env 调用 Node-API 函数之前有效。这包括对 napi_is_exception_pending 的调用,因此可能经常需要复制信息以便以后使用。error_message 中返回的指针指向一个静态定义的字符串,因此如果你在调用另一个 Node-API 函数之前将它从 error_message 字段(将被覆盖)中复制出来,则可以安全地使用该指针。

The content of the napi_extended_error_info returned is only valid up until a Node-API function is called on the same env. This includes a call to napi_is_exception_pending so it may often be necessary to make a copy of the information so that it can be used later. The pointer returned in error_message points to a statically-defined string so it is safe to use that pointer if you have copied it out of the error_message field (which will be overwritten) before another Node-API function was called.

不要依赖任何扩展信息的内容或格式,因为它不受 SemVer 的约束并且可能随时更改。它仅用于记录目的。

Do not rely on the content or format of any of the extended information as it is not subject to SemVer and may change at any time. It is intended only for logging purposes.

即使存在挂起的 JavaScript 异常,也可以调用此 API。

This API can be called even if there is a pending JavaScript exception.

异常#

Exceptions

任何 Node-API 函数调用都可能导致挂起的 JavaScript 异常。任何 API 函数都是这种情况,即使是那些可能不会导致 JavaScript 执行的函数也是如此。

Any Node-API function call may result in a pending JavaScript exception. This is the case for any of the API functions, even those that may not cause the execution of JavaScript.

如果函数返回的 napi_statusnapi_ok,则没有异常挂起,也不需要额外的操作。如果返回的 napi_status 不是 napi_oknapi_pending_exception,为了尝试恢复并继续而不是简单地立即返回,必须调用 napi_is_exception_pending 以确定异常是否挂起。

If the napi_status returned by a function is napi_ok then no exception is pending and no additional action is required. If the napi_status returned is anything other than napi_ok or napi_pending_exception, in order to try to recover and continue instead of simply returning immediately, napi_is_exception_pending must be called in order to determine if an exception is pending or not.

在许多情况下,当调用 Node-API 函数并且异常已经挂起时,该函数将立即返回 napi_statusnapi_pending_exception。然而,并非所有功能都是如此。Node-API 允许调用函数的子集,以便在返回 JavaScript 之前进行一些最小的清理。在这种情况下,napi_status 将反映函数的状态。它不会反映以前未决的异常。为避免混淆,请在每次函数调用后检查错误状态。

In many cases when a Node-API function is called and an exception is already pending, the function will return immediately with a napi_status of napi_pending_exception. However, this is not the case for all functions. Node-API allows a subset of the functions to be called to allow for some minimal cleanup before returning to JavaScript. In that case, napi_status will reflect the status for the function. It will not reflect previous pending exceptions. To avoid confusion, check the error status after every function call.

当异常悬而未决时,可以采用两种方法之一。

When an exception is pending one of two approaches can be employed.

第一种方法是进行任何适当的清理,然后返回,以便执行返回到 JavaScript。作为转换回 JavaScript 的一部分,将在 JavaScript 代码中调用原生方法的位置抛出异常。当异常挂起时,大多数 Node-API 调用的行为是未指定的,许多只会返回 napi_pending_exception,因此尽可能少地执行,然后返回到可以处理异常的 JavaScript。

The first approach is to do any appropriate cleanup and then return so that execution will return to JavaScript. As part of the transition back to JavaScript, the exception will be thrown at the point in the JavaScript code where the native method was invoked. The behavior of most Node-API calls is unspecified while an exception is pending, and many will simply return napi_pending_exception, so do as little as possible and then return to JavaScript where the exception can be handled.

第二种方法是尝试处理异常。在某些情况下,原生代码可以捕获异常,采取适当的操作,然后继续。仅在已知可以安全处理异常的特定情况下才建议这样做。在这些情况下,napi_get_and_clear_last_exception 可用于获取和清除异常。成功时,结果将包含最后抛出的 JavaScript Object 的句柄。如果确定,在检索异常后,异常无法处理,毕竟可以用 napi_throw 重新抛出它,其中 error 是要抛出的 JavaScript 值。

The second approach is to try to handle the exception. There will be cases where the native code can catch the exception, take the appropriate action, and then continue. This is only recommended in specific cases where it is known that the exception can be safely handled. In these cases napi_get_and_clear_last_exception can be used to get and clear the exception. On success, result will contain the handle to the last JavaScript Object thrown. If it is determined, after retrieving the exception, the exception cannot be handled after all it can be re-thrown it with napi_throw where error is the JavaScript value to be thrown.

如果原生代码需要抛出异常或确定 napi_value 是否是 JavaScript Error 对象的实例,还可以使用以下实用函数:napi_throw_errornapi_throw_type_errornapi_throw_range_errornode_api_throw_syntax_errornapi_is_error

The following utility functions are also available in case native code needs to throw an exception or determine if a napi_value is an instance of a JavaScript Error object: napi_throw_error, napi_throw_type_error, napi_throw_range_error, node_api_throw_syntax_error and napi_is_error.

如果原生代码需要创建 Error 对象,还可以使用以下实用函数:napi_create_errornapi_create_type_errornapi_create_range_errornode_api_create_syntax_error,其中结果是指代新创建的 JavaScript Error 对象的 napi_value

The following utility functions are also available in case native code needs to create an Error object: napi_create_error, napi_create_type_error, napi_create_range_error and node_api_create_syntax_error, where result is the napi_value that refers to the newly created JavaScript Error object.

Node.js 项目正在为内部生成的所有错误添加错误代码。目标是让应用使用这些错误代码进行所有错误检查。关联的错误消息将保留,但仅用于记录和显示,期望消息可以在不应用 SemVer 的情况下更改。为了使用 Node-API 支持此模型,无论是内部功能还是模块特定功能(作为其良好实践),throw_create_ 函数采用可选代码参数,该参数是要添加到错误中的代码字符串 目的。如果可选参数是 NULL,则没有代码与错误关联。如果提供了代码,则与错误关联的名称也会更新为:

The Node.js project is adding error codes to all of the errors generated internally. The goal is for applications to use these error codes for all error checking. The associated error messages will remain, but will only be meant to be used for logging and display with the expectation that the message can change without SemVer applying. In order to support this model with Node-API, both in internal functionality and for module specific functionality (as its good practice), the throw_ and create_ functions take an optional code parameter which is the string for the code to be added to the error object. If the optional parameter is NULL then no code will be associated with the error. If a code is provided, the name associated with the error is also updated to be:

originalName [code] 

其中 originalName 是与错误关联的原始名称,code 是提供的代码。例如,如果代码是 'ERR_ERROR_1' 并且正在创建 TypeError,则名称将是:

where originalName is the original name associated with the error and code is the code that was provided. For example, if the code is 'ERR_ERROR_1' and a TypeError is being created the name will be:

TypeError [ERR_ERROR_1] 

napi_throw#
NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] error:要抛出的 JavaScript 值。

    [in] error: The JavaScript value to be thrown.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 抛出提供的 JavaScript 值。

This API throws the JavaScript value provided.

napi_throw_error#
NAPI_EXTERN napi_status napi_throw_error(napi_env env,
                                         const char* code,
                                         const char* msg); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] code:要在错误上设置的可选错误代码。

    [in] code: Optional error code to be set on the error.

  • [in] msg:表示与错误关联的文本的 C 字符串。

    [in] msg: C string representing the text to be associated with the error.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 会抛出带有所提供文本的 JavaScript Error

This API throws a JavaScript Error with the text provided.

napi_throw_type_error#
NAPI_EXTERN napi_status napi_throw_type_error(napi_env env,
                                              const char* code,
                                              const char* msg); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] code:要在错误上设置的可选错误代码。

    [in] code: Optional error code to be set on the error.

  • [in] msg:表示与错误关联的文本的 C 字符串。

    [in] msg: C string representing the text to be associated with the error.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 会抛出带有所提供文本的 JavaScript TypeError

This API throws a JavaScript TypeError with the text provided.

napi_throw_range_error#
NAPI_EXTERN napi_status napi_throw_range_error(napi_env env,
                                               const char* code,
                                               const char* msg); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] code:要在错误上设置的可选错误代码。

    [in] code: Optional error code to be set on the error.

  • [in] msg:表示与错误关联的文本的 C 字符串。

    [in] msg: C string representing the text to be associated with the error.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 会抛出带有所提供文本的 JavaScript RangeError

This API throws a JavaScript RangeError with the text provided.

node_api_throw_syntax_error#
NAPI_EXTERN napi_status node_api_throw_syntax_error(napi_env env,
                                                    const char* code,
                                                    const char* msg); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] code:要在错误上设置的可选错误代码。

    [in] code: Optional error code to be set on the error.

  • [in] msg:表示与错误关联的文本的 C 字符串。

    [in] msg: C string representing the text to be associated with the error.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 会抛出带有所提供文本的 JavaScript SyntaxError

This API throws a JavaScript SyntaxError with the text provided.

napi_is_error#
NAPI_EXTERN napi_status napi_is_error(napi_env env,
                                      napi_value value,
                                      bool* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要检查的 napi_value

    [in] value: The napi_value to be checked.

  • [out] result:如果 napi_value 表示错误,则设置为 true 的布尔值,否则设置为 false。

    [out] result: Boolean value that is set to true if napi_value represents an error, false otherwise.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 查询 napi_value 以检查它是否表示错误对象。

This API queries a napi_value to check if it represents an error object.

napi_create_error#
NAPI_EXTERN napi_status napi_create_error(napi_env env,
                                          napi_value code,
                                          napi_value msg,
                                          napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] code:可选的 napi_value,带有与错误关联的错误代码的字符串。

    [in] code: Optional napi_value with the string for the error code to be associated with the error.

  • [in] msgnapi_value 引用 JavaScript string 用作 Error 的消息。

    [in] msg: napi_value that references a JavaScript string to be used as the message for the Error.

  • [out] resultnapi_value 表示创建的错误。

    [out] result: napi_value representing the error created.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 返回带有所提供文本的 JavaScript Error

This API returns a JavaScript Error with the text provided.

napi_create_type_error#
NAPI_EXTERN napi_status napi_create_type_error(napi_env env,
                                               napi_value code,
                                               napi_value msg,
                                               napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] code:可选的 napi_value,带有与错误关联的错误代码的字符串。

    [in] code: Optional napi_value with the string for the error code to be associated with the error.

  • [in] msgnapi_value 引用 JavaScript string 用作 Error 的消息。

    [in] msg: napi_value that references a JavaScript string to be used as the message for the Error.

  • [out] resultnapi_value 表示创建的错误。

    [out] result: napi_value representing the error created.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 返回带有所提供文本的 JavaScript TypeError

This API returns a JavaScript TypeError with the text provided.

napi_create_range_error#
NAPI_EXTERN napi_status napi_create_range_error(napi_env env,
                                                napi_value code,
                                                napi_value msg,
                                                napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] code:可选的 napi_value,带有与错误关联的错误代码的字符串。

    [in] code: Optional napi_value with the string for the error code to be associated with the error.

  • [in] msgnapi_value 引用 JavaScript string 用作 Error 的消息。

    [in] msg: napi_value that references a JavaScript string to be used as the message for the Error.

  • [out] resultnapi_value 表示创建的错误。

    [out] result: napi_value representing the error created.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 返回带有所提供文本的 JavaScript RangeError

This API returns a JavaScript RangeError with the text provided.

node_api_create_syntax_error#
NAPI_EXTERN napi_status node_api_create_syntax_error(napi_env env,
                                                     napi_value code,
                                                     napi_value msg,
                                                     napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] code:可选的 napi_value,带有与错误关联的错误代码的字符串。

    [in] code: Optional napi_value with the string for the error code to be associated with the error.

  • [in] msgnapi_value 引用 JavaScript string 用作 Error 的消息。

    [in] msg: napi_value that references a JavaScript string to be used as the message for the Error.

  • [out] resultnapi_value 表示创建的错误。

    [out] result: napi_value representing the error created.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 返回带有所提供文本的 JavaScript SyntaxError

This API returns a JavaScript SyntaxError with the text provided.

napi_get_and_clear_last_exception#
napi_status napi_get_and_clear_last_exception(napi_env env,
                                              napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [out] result:如果一个未决则异常,否则为 NULL

    [out] result: The exception if one is pending, NULL otherwise.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

即使存在挂起的 JavaScript 异常,也可以调用此 API。

This API can be called even if there is a pending JavaScript exception.

napi_is_exception_pending#
napi_status napi_is_exception_pending(napi_env env, bool* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [out] result:如果异常挂起,则设置为 true 的布尔值。

    [out] result: Boolean value that is set to true if an exception is pending.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

即使存在挂起的 JavaScript 异常,也可以调用此 API。

This API can be called even if there is a pending JavaScript exception.

napi_fatal_exception#
napi_status napi_fatal_exception(napi_env env, napi_value err); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] err:传递给 'uncaughtException' 的错误。

    [in] err: The error that is passed to 'uncaughtException'.

在 JavaScript 中触发 'uncaughtException'。如果异步回调抛出无法恢复的异常,则很有用。

Trigger an 'uncaughtException' in JavaScript. Useful if an async callback throws an exception with no way to recover.

致命错误#

Fatal errors

如果原生插件中出现不可恢复的错误,则可以抛出致命错误以立即终止进程。

In the event of an unrecoverable error in a native addon, a fatal error can be thrown to immediately terminate the process.

napi_fatal_error#
NAPI_NO_RETURN void napi_fatal_error(const char* location,
                                     size_t location_len,
                                     const char* message,
                                     size_t message_len); 
  • [in] location:发生错误的可选位置。

    [in] location: Optional location at which the error occurred.

  • [in] location_len:位置的长度(以字节为单位),如果它以 null 结尾则为 NAPI_AUTO_LENGTH

    [in] location_len: The length of the location in bytes, or NAPI_AUTO_LENGTH if it is null-terminated.

  • [in] message:与错误关联的消息。

    [in] message: The message associated with the error.

  • [in] message_len:消息的长度(以字节为单位),如果以 null 结尾则为 NAPI_AUTO_LENGTH

    [in] message_len: The length of the message in bytes, or NAPI_AUTO_LENGTH if it is null-terminated.

函数调用不返回,进程将终止。

The function call does not return, the process will be terminated.

即使存在挂起的 JavaScript 异常,也可以调用此 API。

This API can be called even if there is a pending JavaScript exception.

对象生命周期管理#

Object lifetime management

在进行 Node-API 调用时,底层 VM 的堆中对象的句柄可能会作为 napi_values 返回。这些句柄必须持有对象 'live',直到原生代码不再需要它们,否则这些对象可能会在原生代码使用完它们之前被收集。

As Node-API calls are made, handles to objects in the heap for the underlying VM may be returned as napi_values. These handles must hold the objects 'live' until they are no longer required by the native code, otherwise the objects could be collected before the native code was finished using them.

当对象句柄返回时,它们与 'scope' 相关联。默认作用域的生命周期与本地方法调用的生命周期相关。结果是,默认情况下,句柄保持有效,并且与这些句柄关联的对象将在原生方法调用的生命周期内保持活动状态。

As object handles are returned they are associated with a 'scope'. The lifespan for the default scope is tied to the lifespan of the native method call. The result is that, by default, handles remain valid and the objects associated with these handles will be held live for the lifespan of the native method call.

然而,在许多情况下,句柄必须在比本地方法更短或更长的生命周期内保持有效。以下部分描述了可用于更改默认句柄寿命的 Node-API 函数。

In many cases, however, it is necessary that the handles remain valid for either a shorter or longer lifespan than that of the native method. The sections which follow describe the Node-API functions that can be used to change the handle lifespan from the default.

使句柄寿命短于本地方法#

Making handle lifespan shorter than that of the native method

通常需要使句柄的生命周期短于本地方法的生命周期。例如,考虑一个本地方法,它有一个循环遍历大型数组中的元素:

It is often necessary to make the lifespan of handles shorter than the lifespan of a native method. For example, consider a native method that has a loop which iterates through the elements in a large array:

for (int i = 0; i < 1000000; i++) {
  napi_value result;
  napi_status status = napi_get_element(env, object, i, &result);
  if (status != napi_ok) {
    break;
  }
  // do something with element
} 

这将导致创建大量句柄,消耗大量资源。此外,即使原生代码只能使用最近的句柄,所有关联的对象也将保持活动状态,因为它们都共享相同的范围。

This would result in a large number of handles being created, consuming substantial resources. In addition, even though the native code could only use the most recent handle, all of the associated objects would also be kept alive since they all share the same scope.

为了处理这种情况,Node-API 提供了建立新的 'scope' 的能力,新创建的句柄将与之关联。一旦不再需要这些句柄,范围可以是 'closed',并且与该范围关联的任何句柄都将失效。可用于打开/关闭范围的方法是 napi_open_handle_scopenapi_close_handle_scope

To handle this case, Node-API provides the ability to establish a new 'scope' to which newly created handles will be associated. Once those handles are no longer required, the scope can be 'closed' and any handles associated with the scope are invalidated. The methods available to open/close scopes are napi_open_handle_scope and napi_close_handle_scope.

Node-API 仅支持单个嵌套的范围层次结构。任何时候都只有一个活动范围,所有新句柄都将与该范围关联,同时它处于活动状态。必须按照打开范围的相反顺序关闭范围。此外,在从该方法返回之前,必须关闭在原生方法中创建的所有作用域。

Node-API only supports a single nested hierarchy of scopes. There is only one active scope at any time, and all new handles will be associated with that scope while it is active. Scopes must be closed in the reverse order from which they are opened. In addition, all scopes created within a native method must be closed before returning from that method.

以前面的例子为例,添加对 napi_open_handle_scopenapi_close_handle_scope 的调用将确保在整个循环执行过程中最多只有一个句柄有效:

Taking the earlier example, adding calls to napi_open_handle_scope and napi_close_handle_scope would ensure that at most a single handle is valid throughout the execution of the loop:

for (int i = 0; i < 1000000; i++) {
  napi_handle_scope scope;
  napi_status status = napi_open_handle_scope(env, &scope);
  if (status != napi_ok) {
    break;
  }
  napi_value result;
  status = napi_get_element(env, object, i, &result);
  if (status != napi_ok) {
    break;
  }
  // do something with element
  status = napi_close_handle_scope(env, scope);
  if (status != napi_ok) {
    break;
  }
} 

嵌套作用域时,有时内部作用域的句柄需要超出该作用域的生命周期。Node-API 支持 '可转义的范围' 以支持这种情况。可转义作用域允许一个句柄为 'promoted',以便 'escapes' 当前作用域和句柄的生命周期从当前作用域变为外部作用域。

When nesting scopes, there are cases where a handle from an inner scope needs to live beyond the lifespan of that scope. Node-API supports an 'escapable scope' in order to support this case. An escapable scope allows one handle to be 'promoted' so that it 'escapes' the current scope and the lifespan of the handle changes from the current scope to that of the outer scope.

可用于打开/关闭可转义范围的方法是 napi_open_escapable_handle_scopenapi_close_escapable_handle_scope

The methods available to open/close escapable scopes are napi_open_escapable_handle_scope and napi_close_escapable_handle_scope.

提升句柄的请求是通过 napi_escape_handle 触发的,只能调用一次。

The request to promote a handle is made through napi_escape_handle which can only be called once.

napi_open_handle_scope#
NAPI_EXTERN napi_status napi_open_handle_scope(napi_env env,
                                               napi_handle_scope* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [out] resultnapi_value 代表新范围。

    [out] result: napi_value representing the new scope.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 开辟了一个新的范围。

This API opens a new scope.

napi_close_handle_scope#
NAPI_EXTERN napi_status napi_close_handle_scope(napi_env env,
                                                napi_handle_scope scope); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] scopenapi_value 表示要关闭的范围。

    [in] scope: napi_value representing the scope to be closed.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 关闭传入的范围。必须按照创建范围的相反顺序关闭范围。

This API closes the scope passed in. Scopes must be closed in the reverse order from which they were created.

即使存在挂起的 JavaScript 异常,也可以调用此 API。

This API can be called even if there is a pending JavaScript exception.

napi_open_escapable_handle_scope#
NAPI_EXTERN napi_status
    napi_open_escapable_handle_scope(napi_env env,
                                     napi_handle_scope* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [out] resultnapi_value 代表新范围。

    [out] result: napi_value representing the new scope.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 会打开一个新范围,从中可以将一个对象提升到外部范围。

This API opens a new scope from which one object can be promoted to the outer scope.

napi_close_escapable_handle_scope#
NAPI_EXTERN napi_status
    napi_close_escapable_handle_scope(napi_env env,
                                      napi_handle_scope scope); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] scopenapi_value 表示要关闭的范围。

    [in] scope: napi_value representing the scope to be closed.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 关闭传入的范围。必须按照创建范围的相反顺序关闭范围。

This API closes the scope passed in. Scopes must be closed in the reverse order from which they were created.

即使存在挂起的 JavaScript 异常,也可以调用此 API。

This API can be called even if there is a pending JavaScript exception.

napi_escape_handle#
napi_status napi_escape_handle(napi_env env,
                               napi_escapable_handle_scope scope,
                               napi_value escapee,
                               napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] scopenapi_value 代表当前范围。

    [in] scope: napi_value representing the current scope.

  • [in] escapeenapi_value 表示要转义的 JavaScript Object

    [in] escapee: napi_value representing the JavaScript Object to be escaped.

  • [out] resultnapi_value 表示外部作用域中转义的 Object 的句柄。

    [out] result: napi_value representing the handle to the escaped Object in the outer scope.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 提升 JavaScript 对象的句柄,使其在外部作用域的生命周期内有效。每个作用域只能调用一次。如果多次调用,将返回错误。

This API promotes the handle to the JavaScript object so that it is valid for the lifetime of the outer scope. It can only be called once per scope. If it is called more than once an error will be returned.

即使存在挂起的 JavaScript 异常,也可以调用此 API。

This API can be called even if there is a pending JavaScript exception.

对生命周期比原生方法长的值的引用#

References to values with a lifespan longer than that of the native method

在某些情况下,插件需要能够创建和引用生命周期比单个本地方法调用更长的值。例如,要创建构造函数并稍后在创建实例的请求中使用该构造函数,必须可以在许多不同的实例创建请求中引用构造函数对象。这对于如前一节所述作为 napi_value 返回的普通句柄是不可能的。普通句柄的生命周期由作用域管理,所有作用域都必须在本地方法结束之前关闭。

In some cases, an addon will need to be able to create and reference values with a lifespan longer than that of a single native method invocation. For example, to create a constructor and later use that constructor in a request to create instances, it must be possible to reference the constructor object across many different instance creation requests. This would not be possible with a normal handle returned as a napi_value as described in the earlier section. The lifespan of a normal handle is managed by scopes and all scopes must be closed before the end of a native method.

Node-API 提供了创建对值的持久引用的方法。目前 Node-API 只允许为一组有限的值类型创建引用,包括对象、外部、函数和符号。

Node-API provides methods for creating persistent references to values. Currently Node-API only allows references to be created for a limited set of value types, including object, external, function, and symbol.

每个引用都有一个值为 0 或更高的关联计数,这决定了引用是否会使相应的值保持活动状态。计数为 0 的引用不会阻止收集值。对象(对象、函数、外部)和符号类型的值正在成为 'weak' 引用,并且在未收集时仍然可以访问。任何大于 0 的计数都将阻止收集值。

Each reference has an associated count with a value of 0 or higher, which determines whether the reference will keep the corresponding value alive. References with a count of 0 do not prevent values from being collected. Values of object (object, function, external) and symbol types are becoming 'weak' references and can still be accessed while they are not collected. Any count greater than 0 will prevent the values from being collected.

符号值有不同的风格。只有使用 napi_create_symbol 函数或 JavaScript Symbol() 构造函数调用创建的局部符号才支持真正的弱引用行为。使用 node_api_symbol_for 函数或 JavaScript Symbol.for() 函数调用创建的全局注册符号始终保持强引用,因为垃圾收集器不会收集它们。Symbol.iterator 等知名符号也是如此。它们也永远不会被垃圾收集器收集。

Symbol values have different flavors. The true weak reference behavior is only supported by local symbols created with the napi_create_symbol function or the JavaScript Symbol() constructor calls. Globally registered symbols created with the node_api_symbol_for function or JavaScript Symbol.for() function calls remain always strong references because the garbage collector does not collect them. The same is true for well-known symbols such as Symbol.iterator. They are also never collected by the garbage collector.

可以使用初始引用计数创建引用。然后可以通过 napi_reference_refnapi_reference_unref 修改计数。如果在引用计数为 0 时收集对象,则所有后续调用以获取与引用 napi_get_reference_value 关联的对象将为返回的 napi_value 返回 NULL。尝试为其对象已收集的引用调用 napi_reference_ref 会导致错误。

References can be created with an initial reference count. The count can then be modified through napi_reference_ref and napi_reference_unref. If an object is collected while the count for a reference is 0, all subsequent calls to get the object associated with the reference napi_get_reference_value will return NULL for the returned napi_value. An attempt to call napi_reference_ref for a reference whose object has been collected results in an error.

一旦插件不再需要引用,就必须删除它们。删除引用后,将不再阻止收集相应的对象。未能删除持久引用会导致 '内存泄漏' 永久保留用于持久引用的原生内存和堆上的相应对象。

References must be deleted once they are no longer required by the addon. When a reference is deleted, it will no longer prevent the corresponding object from being collected. Failure to delete a persistent reference results in a 'memory leak' with both the native memory for the persistent reference and the corresponding object on the heap being retained forever.

可以创建多个指向同一个对象的持久引用,每个持久引用将根据其各自的计数使对象保持活动状态。对同一对象的多个持久引用可能会导致原生内存意外保持活动状态。持久引用的原生结构必须保持活动状态,直到执行引用对象的终结器。如果为同一对象创建新的持久引用,则不会运行该对象的终结器,并且不会释放先前持久引用指向的原生内存。这可以通过在可能的情况下除了 napi_reference_unref 之外还调用 napi_delete_reference 来避免。

There can be multiple persistent references created which refer to the same object, each of which will either keep the object live or not based on its individual count. Multiple persistent references to the same object can result in unexpectedly keeping alive native memory. The native structures for a persistent reference must be kept alive until finalizers for the referenced object are executed. If a new persistent reference is created for the same object, the finalizers for that object will not be run and the native memory pointed by the earlier persistent reference will not be freed. This can be avoided by calling napi_delete_reference in addition to napi_reference_unref when possible.

变更历史:

Change History:

  • 实验性的(定义了 NAPI_EXPERIMENTAL):

    Experimental (NAPI_EXPERIMENTAL is defined):

    可以为所有值类型创建引用。新支持的值类型不支持弱引用语义,当引用计数变为 0 并且无法再从引用访问时,这些类型的值将被释放。

    References can be created for all value types. The new supported value types do not support weak reference semantic and the values of these types are released when the reference count becomes 0 and cannot be accessed from the reference anymore.

napi_create_reference#
NAPI_EXTERN napi_status napi_create_reference(napi_env env,
                                              napi_value value,
                                              uint32_t initial_refcount,
                                              napi_ref* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:正在为其创建引用的 napi_value

    [in] value: The napi_value for which a reference is being created.

  • [in] initial_refcount:新引用的初始引用计数。

    [in] initial_refcount: Initial reference count for the new reference.

  • [out] resultnapi_ref 指向新的引用。

    [out] result: napi_ref pointing to the new reference.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 对传入的值创建一个具有指定引用计数的新引用。

This API creates a new reference with the specified reference count to the value passed in.

napi_delete_reference#
NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] refnapi_ref 被删除。

    [in] ref: napi_ref to be deleted.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 删除传入的引用。

This API deletes the reference passed in.

即使存在挂起的 JavaScript 异常,也可以调用此 API。

This API can be called even if there is a pending JavaScript exception.

napi_reference_ref#
NAPI_EXTERN napi_status napi_reference_ref(napi_env env,
                                           napi_ref ref,
                                           uint32_t* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] refnapi_ref,其引用计数将增加。

    [in] ref: napi_ref for which the reference count will be incremented.

  • [out] result:新的引用计数。

    [out] result: The new reference count.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 增加传入引用的引用计数并返回生成的引用计数。

This API increments the reference count for the reference passed in and returns the resulting reference count.

napi_reference_unref#
NAPI_EXTERN napi_status napi_reference_unref(napi_env env,
                                             napi_ref ref,
                                             uint32_t* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] ref:将减少其引用计数的 napi_ref

    [in] ref: napi_ref for which the reference count will be decremented.

  • [out] result:新的引用计数。

    [out] result: The new reference count.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 递减传入引用的引用计数并返回生成的引用计数。

This API decrements the reference count for the reference passed in and returns the resulting reference count.

napi_get_reference_value#
NAPI_EXTERN napi_status napi_get_reference_value(napi_env env,
                                                 napi_ref ref,
                                                 napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] ref:请求相应值的 napi_ref

    [in] ref: The napi_ref for which the corresponding value is being requested.

  • [out] resultnapi_ref 引用的 napi_value

    [out] result: The napi_value referenced by the napi_ref.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

如果仍然有效,此 API 将返回 napi_value,表示与 napi_ref 关联的 JavaScript 值。否则,结果将为 NULL

If still valid, this API returns the napi_value representing the JavaScript value associated with the napi_ref. Otherwise, result will be NULL.

当前 Node.js 环境退出时的清理#

Cleanup on exit of the current Node.js environment

虽然 Node.js 进程通常会在退出时释放其所有资源,但 Node.js 的嵌入程序或未来的 Worker 支持可能需要插件来注册清理钩子,一旦当前 Node.js 环境退出,这些钩子就会运行。

While a Node.js process typically releases all its resources when exiting, embedders of Node.js, or future Worker support, may require addons to register clean-up hooks that will be run once the current Node.js environment exits.

Node-API 提供了注册和取消注册此类回调的功能。当这些回调运行时,插件持有的所有资源都应该被释放。

Node-API provides functions for registering and un-registering such callbacks. When those callbacks are run, all resources that are being held by the addon should be freed up.

napi_add_env_cleanup_hook#
NODE_EXTERN napi_status napi_add_env_cleanup_hook(napi_env env,
                                                  napi_cleanup_hook fun,
                                                  void* arg); 

一旦当前 Node.js 环境退出,将 fun 注册为要使用 arg 参数运行的函数。

Registers fun as a function to be run with the arg parameter once the current Node.js environment exits.

可以使用不同的 arg 值安全地多次指定一个函数。在这种情况下,它也会被多次调用。不允许多次提供相同的 funarg 值,否则会导致进程中止。

A function can safely be specified multiple times with different arg values. In that case, it will be called multiple times as well. Providing the same fun and arg values multiple times is not allowed and will lead the process to abort.

钩子将以相反的顺序调用,即最近添加的钩子将首先被调用。

The hooks will be called in reverse order, i.e. the most recently added one will be called first.

可以使用 napi_remove_env_cleanup_hook 删除此钩子。通常,当为其添加此钩子的资源无论如何都被拆除时,就会发生这种情况。

Removing this hook can be done by using napi_remove_env_cleanup_hook. Typically, that happens when the resource for which this hook was added is being torn down anyway.

对于异步清理,napi_add_async_cleanup_hook 可用。

For asynchronous cleanup, napi_add_async_cleanup_hook is available.

napi_remove_env_cleanup_hook#
NAPI_EXTERN napi_status napi_remove_env_cleanup_hook(napi_env env,
                                                     void (*fun)(void* arg),
                                                     void* arg); 

一旦当前 Node.js 环境退出,将 fun 注销为要使用 arg 参数运行的函数。参数和函数值都需要完全匹配。

Unregisters fun as a function to be run with the arg parameter once the current Node.js environment exits. Both the argument and the function value need to be exact matches.

该函数必须最初已注册到 napi_add_env_cleanup_hook,否则进程将中止。

The function must have originally been registered with napi_add_env_cleanup_hook, otherwise the process will abort.

napi_add_async_cleanup_hook#
NAPI_EXTERN napi_status napi_add_async_cleanup_hook(
    napi_env env,
    napi_async_cleanup_hook hook,
    void* arg,
    napi_async_cleanup_hook_handle* remove_handle); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] hook:在环境拆卸时调用的函数指针。

    [in] hook: The function pointer to call at environment teardown.

  • [in] arg:调用时传递给 hook 的指针。

    [in] arg: The pointer to pass to hook when it gets called.

  • [out] remove_handle:引用异步清理钩子的可选句柄。

    [out] remove_handle: Optional handle that refers to the asynchronous cleanup hook.

hook 注册为 napi_async_cleanup_hook 类型的函数,作为在当前 Node.js 环境退出后使用 remove_handlearg 参数运行的函数。

Registers hook, which is a function of type napi_async_cleanup_hook, as a function to be run with the remove_handle and arg parameters once the current Node.js environment exits.

napi_add_env_cleanup_hook 不同的是,hook 允许是异步的。

Unlike napi_add_env_cleanup_hook, the hook is allowed to be asynchronous.

否则,行为通常与 napi_add_env_cleanup_hook 的行为相匹配。

Otherwise, behavior generally matches that of napi_add_env_cleanup_hook.

如果 remove_handle 不是 NULL,则将在其中存储一个不透明的值,该值稍后必须传递给 napi_remove_async_cleanup_hook,无论钩子是否已被调用。通常,当为其添加此钩子的资源无论如何都被拆除时,就会发生这种情况。

If remove_handle is not NULL, an opaque value will be stored in it that must later be passed to napi_remove_async_cleanup_hook, regardless of whether the hook has already been invoked. Typically, that happens when the resource for which this hook was added is being torn down anyway.

napi_remove_async_cleanup_hook#
NAPI_EXTERN napi_status napi_remove_async_cleanup_hook(
    napi_async_cleanup_hook_handle remove_handle); 

注销对应于 remove_handle 的清除钩子。这将阻止执行钩子,除非它已经开始执行。这必须在从 napi_add_async_cleanup_hook 获得的任何 napi_async_cleanup_hook_handle 值上调用。

Unregisters the cleanup hook corresponding to remove_handle. This will prevent the hook from being executed, unless it has already started executing. This must be called on any napi_async_cleanup_hook_handle value obtained from napi_add_async_cleanup_hook.

在 Node.js 环境退出时完成#

Finalization on the exit of the Node.js environment

Node.js 环境可能会在任意时间尽快拆除,不允许 JavaScript 执行,就像 worker.terminate() 的请求一样。当环境被拆除时,JavaScript 对象、线程安全函数和环境实例数据的已注册 napi_finalize 回调将立即独立调用。

The Node.js environment may be torn down at an arbitrary time as soon as possible with JavaScript execution disallowed, like on the request of worker.terminate(). When the environment is being torn down, the registered napi_finalize callbacks of JavaScript objects, thread-safe functions and environment instance data are invoked immediately and independently.

napi_finalize 回调的调用安排在手动注册的清理钩子之后。为了确保在环境关闭期间插件完成的正确顺序以避免 napi_finalize 回调中的释放后使用,插件应该向 napi_add_env_cleanup_hooknapi_add_async_cleanup_hook 注册一个清理钩子,以便以正确的顺序手动释放分配的资源。

The invocation of napi_finalize callbacks is scheduled after the manually registered cleanup hooks. In order to ensure a proper order of addon finalization during environment shutdown to avoid use-after-free in the napi_finalize callback, addons should register a cleanup hook with napi_add_env_cleanup_hook and napi_add_async_cleanup_hook to manually release the allocated resource in a proper order.

模块注册#

Module registration

Node-API 模块的注册方式与其他模块类似,只是不使用 NODE_MODULE 宏,而是使用以下内容:

Node-API modules are registered in a manner similar to other modules except that instead of using the NODE_MODULE macro the following is used:

NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) 

下一个区别是 Init 方法的签名。对于 Node-API 模块,它如下所示:

The next difference is the signature for the Init method. For a Node-API module it is as follows:

napi_value Init(napi_env env, napi_value exports); 

Init 的返回值被视为模块的 exports 对象。为方便起见,Init 方法通过 exports 参数传递一个空对象。如果 Init 返回 NULL,则作为 exports 传递的参数由模块导出。Node-API 模块无法修改 module 对象,但可以将任何内容指定为模块的 exports 属性。

The return value from Init is treated as the exports object for the module. The Init method is passed an empty object via the exports parameter as a convenience. If Init returns NULL, the parameter passed as exports is exported by the module. Node-API modules cannot modify the module object but can specify anything as the exports property of the module.

将方法 hello 添加为函数,以便它可以作为插件提供的方法调用:

To add the method hello as a function so that it can be called as a method provided by the addon:

napi_value Init(napi_env env, napi_value exports) {
  napi_status status;
  napi_property_descriptor desc = {
    "hello",
    NULL,
    Method,
    NULL,
    NULL,
    NULL,
    napi_writable | napi_enumerable | napi_configurable,
    NULL
  };
  status = napi_define_properties(env, exports, 1, &desc);
  if (status != napi_ok) return NULL;
  return exports;
} 

要为插件设置 require() 返回的函数:

To set a function to be returned by the require() for the addon:

napi_value Init(napi_env env, napi_value exports) {
  napi_value method;
  napi_status status;
  status = napi_create_function(env, "exports", NAPI_AUTO_LENGTH, Method, NULL, &method);
  if (status != napi_ok) return NULL;
  return method;
} 

定义一个类以便创建新实例(通常与 对象封装 一起使用):

To define a class so that new instances can be created (often used with Object wrap):

// NOTE: partial example, not all referenced code is included
napi_value Init(napi_env env, napi_value exports) {
  napi_status status;
  napi_property_descriptor properties[] = {
    { "value", NULL, NULL, GetValue, SetValue, NULL, napi_writable | napi_configurable, NULL },
    DECLARE_NAPI_METHOD("plusOne", PlusOne),
    DECLARE_NAPI_METHOD("multiply", Multiply),
  };

  napi_value cons;
  status =
      napi_define_class(env, "MyObject", New, NULL, 3, properties, &cons);
  if (status != napi_ok) return NULL;

  status = napi_create_reference(env, cons, 1, &constructor);
  if (status != napi_ok) return NULL;

  status = napi_set_named_property(env, exports, "MyObject", cons);
  if (status != napi_ok) return NULL;

  return exports;
} 

你还可以使用 NAPI_MODULE_INIT 宏,它充当 NAPI_MODULE 的简写并定义 Init 函数:

You can also use the NAPI_MODULE_INIT macro, which acts as a shorthand for NAPI_MODULE and defining an Init function:

NAPI_MODULE_INIT() {
  napi_value answer;
  napi_status result;

  status = napi_create_int64(env, 42, &answer);
  if (status != napi_ok) return NULL;

  status = napi_set_named_property(env, exports, "answer", answer);
  if (status != napi_ok) return NULL;

  return exports;
} 

所有 Node-API 插件都是上下文感知的,这意味着它们可以被加载多次。声明此类模块时有一些设计注意事项。上下文感知的插件 上的文档提供了更多详细信息。

All Node-API addons are context-aware, meaning they may be loaded multiple times. There are a few design considerations when declaring such a module. The documentation on context-aware addons provides more details.

宏调用后,变量 envexports 将在函数体内可用。

The variables env and exports will be available inside the function body following the macro invocation.

有关设置对象属性的更多详细信息,请参阅 使用 JavaScript 属性 部分。

For more details on setting properties on objects, see the section on Working with JavaScript properties.

有关一般构建插件模块的更多详细信息,请参阅现有 API。

For more details on building addon modules in general, refer to the existing API.

使用 JavaScript 值#

Working with JavaScript values

Node-API 公开了一组 API 来创建所有类型的 JavaScript 值。其中一些类型记录在 ECMAScript 语言规范第 6 节 下。

Node-API exposes a set of APIs to create all types of JavaScript values. Some of these types are documented under Section 6 of the ECMAScript Language Specification.

从根本上说,这些 API 用于执行以下操作之一:

Fundamentally, these APIs are used to do one of the following:

  1. 创建一个新的 JavaScript 对象

    Create a new JavaScript object

  2. 从原始 C 类型转换为 Node-API 值

    Convert from a primitive C type to a Node-API value

  3. 从 Node-API 值转换为原始 C 类型

    Convert from Node-API value to a primitive C type

  4. 获取全局实例包括 undefinednull

    Get global instances including undefined and null

Node-API 值由类型 napi_value 表示。任何需要 JavaScript 值的 Node-API 调用都采用 napi_value。在某些情况下,API 会预先检查 napi_value 的类型。但是,为了获得更好的性能,调用者最好确保所讨论的 napi_value 是 API 期望的 JavaScript 类型。

Node-API values are represented by the type napi_value. Any Node-API call that requires a JavaScript value takes in a napi_value. In some cases, the API does check the type of the napi_value up-front. However, for better performance, it's better for the caller to make sure that the napi_value in question is of the JavaScript type expected by the API.

枚举类型#

Enum types

napi_key_collection_mode#
typedef enum {
  napi_key_include_prototypes,
  napi_key_own_only
} napi_key_collection_mode; 

描述 Keys/Properties 过滤器枚举:

Describes the Keys/Properties filter enums:

napi_key_collection_mode 限制了收集属性的范围。

napi_key_collection_mode limits the range of collected properties.

napi_key_own_only 将收集的属性仅限于给定的对象。napi_key_include_prototypes 也将包含对象原型链的所有键。

napi_key_own_only limits the collected properties to the given object only. napi_key_include_prototypes will include all keys of the objects's prototype chain as well.

napi_key_filter#
typedef enum {
  napi_key_all_properties = 0,
  napi_key_writable = 1,
  napi_key_enumerable = 1 << 1,
  napi_key_configurable = 1 << 2,
  napi_key_skip_strings = 1 << 3,
  napi_key_skip_symbols = 1 << 4
} napi_key_filter; 

属性过滤器位。它们可以被 or' 构建一个复合过滤器。

Property filter bits. They can be or'ed to build a composite filter.

napi_key_conversion#
typedef enum {
  napi_key_keep_numbers,
  napi_key_numbers_to_strings
} napi_key_conversion; 

napi_key_numbers_to_strings 会将整数索引转换为字符串。napi_key_keep_numbers 将返回整数索引的数字。

napi_key_numbers_to_strings will convert integer indices to strings. napi_key_keep_numbers will return numbers for integer indices.

napi_valuetype#
typedef enum {
  // ES6 types (corresponds to typeof)
  napi_undefined,
  napi_null,
  napi_boolean,
  napi_number,
  napi_string,
  napi_symbol,
  napi_object,
  napi_function,
  napi_external,
  napi_bigint,
} napi_valuetype; 

描述 napi_value 的类型。这通常对应于 ECMAScript 语言规范的 第 6.1 节 中描述的类型。除了该部分中的类型外,napi_valuetype 还可以用外部数据表示 FunctionObject

Describes the type of a napi_value. This generally corresponds to the types described in Section 6.1 of the ECMAScript Language Specification. In addition to types in that section, napi_valuetype can also represent Functions and Objects with external data.

napi_external 类型的 JavaScript 值在 JavaScript 中显示为普通对象,因此不能在其上设置任何属性,也没有原型。

A JavaScript value of type napi_external appears in JavaScript as a plain object such that no properties can be set on it, and no prototype.

napi_typedarray_type#
typedef enum {
  napi_int8_array,
  napi_uint8_array,
  napi_uint8_clamped_array,
  napi_int16_array,
  napi_uint16_array,
  napi_int32_array,
  napi_uint32_array,
  napi_float32_array,
  napi_float64_array,
  napi_bigint64_array,
  napi_biguint64_array,
} napi_typedarray_type; 

这表示 TypedArray 的基础二进制标量数据类型。此枚举的元素对应于 ECMAScript 语言规范第 22.2 节

This represents the underlying binary scalar datatype of the TypedArray. Elements of this enum correspond to Section 22.2 of the ECMAScript Language Specification.

对象创建函数#

Object creation functions

napi_create_array#
napi_status napi_create_array(napi_env env, napi_value* result) 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [out] result:代表 JavaScript Arraynapi_value

    [out] result: A napi_value representing a JavaScript Array.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 返回对应于 JavaScript Array 类型的 Node-API 值。JavaScript 数组在 ECMAScript 语言规范的 第 22.1 节 中进行了描述。

This API returns a Node-API value corresponding to a JavaScript Array type. JavaScript arrays are described in Section 22.1 of the ECMAScript Language Specification.

napi_create_array_with_length#
napi_status napi_create_array_with_length(napi_env env,
                                          size_t length,
                                          napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] lengthArray 的初始长度。

    [in] length: The initial length of the Array.

  • [out] result:代表 JavaScript Arraynapi_value

    [out] result: A napi_value representing a JavaScript Array.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 返回对应于 JavaScript Array 类型的 Node-API 值。Array 的长度属性设置为传入的长度参数。但是,不保证底层缓冲区在创建数组时由 VM 预先分配。该行为留给底层 VM 实现。如果缓冲区必须是可以通过 C 直接读取和/或写入的连续内存块,请考虑使用 napi_create_external_arraybuffer

This API returns a Node-API value corresponding to a JavaScript Array type. The Array's length property is set to the passed-in length parameter. However, the underlying buffer is not guaranteed to be pre-allocated by the VM when the array is created. That behavior is left to the underlying VM implementation. If the buffer must be a contiguous block of memory that can be directly read and/or written via C, consider using napi_create_external_arraybuffer.

JavaScript 数组在 ECMAScript 语言规范的 第 22.1 节 中进行了描述。

JavaScript arrays are described in Section 22.1 of the ECMAScript Language Specification.

napi_create_arraybuffer#
napi_status napi_create_arraybuffer(napi_env env,
                                    size_t byte_length,
                                    void** data,
                                    napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] length:要创建的数组缓冲区的字节长度。

    [in] length: The length in bytes of the array buffer to create.

  • [out] data:指向 ArrayBuffer 的底层字节缓冲区的指针。data 可以选择性地通过传递 NULL 来忽略。

    [out] data: Pointer to the underlying byte buffer of the ArrayBuffer. data can optionally be ignored by passing NULL.

  • [out] result:代表 JavaScript ArrayBuffernapi_value

    [out] result: A napi_value representing a JavaScript ArrayBuffer.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 返回对应于 JavaScript ArrayBuffer 的 Node-API 值。ArrayBuffer 用于表示固定长度的二进制数据缓冲区。它们通常用作 TypedArray 对象的后备缓冲区。分配的 ArrayBuffer 将有一个底层字节缓冲区,其大小由传入的 length 参数决定。如果调用者想要直接操作缓冲区,则可以选择将底层缓冲区返回给调用者。此缓冲区只能直接从原生代码写入。要从 JavaScript 写入此缓冲区,需要创建类型化数组或 DataView 对象。

This API returns a Node-API value corresponding to a JavaScript ArrayBuffer. ArrayBuffers are used to represent fixed-length binary data buffers. They are normally used as a backing-buffer for TypedArray objects. The ArrayBuffer allocated will have an underlying byte buffer whose size is determined by the length parameter that's passed in. The underlying buffer is optionally returned back to the caller in case the caller wants to directly manipulate the buffer. This buffer can only be written to directly from native code. To write to this buffer from JavaScript, a typed array or DataView object would need to be created.

JavaScript ArrayBuffer 对象在 ECMAScript 语言规范的 第 24.1 节 中进行了描述。

JavaScript ArrayBuffer objects are described in Section 24.1 of the ECMAScript Language Specification.

napi_create_buffer#
napi_status napi_create_buffer(napi_env env,
                               size_t size,
                               void** data,
                               napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] size:底层缓冲区的大小(以字节为单位)。

    [in] size: Size in bytes of the underlying buffer.

  • [out] data:指向底层缓冲区的原始指针。data 可以选择性地通过传递 NULL 来忽略。

    [out] data: Raw pointer to the underlying buffer. data can optionally be ignored by passing NULL.

  • [out] result:一个 napi_value 代表一个 node::Buffer

    [out] result: A napi_value representing a node::Buffer.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 分配一个 node::Buffer 对象。虽然这仍然是一个完全受支持的数据结构,但在大多数情况下使用 TypedArray 就足够了。

This API allocates a node::Buffer object. While this is still a fully-supported data structure, in most cases using a TypedArray will suffice.

napi_create_buffer_copy#
napi_status napi_create_buffer_copy(napi_env env,
                                    size_t length,
                                    const void* data,
                                    void** result_data,
                                    napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] size:输入缓冲区的大小(以字节为单位)(应与新缓冲区的大小相同)。

    [in] size: Size in bytes of the input buffer (should be the same as the size of the new buffer).

  • [in] data:指向要从中复制的基础缓冲区的原始指针。

    [in] data: Raw pointer to the underlying buffer to copy from.

  • [out] result_data:指向新 Buffer 的基础数据缓冲区的指针。result_data 可以选择性地通过传递 NULL 来忽略。

    [out] result_data: Pointer to the new Buffer's underlying data buffer. result_data can optionally be ignored by passing NULL.

  • [out] result:一个 napi_value 代表一个 node::Buffer

    [out] result: A napi_value representing a node::Buffer.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 分配一个 node::Buffer 对象并使用从传入缓冲区复制的数据对其进行初始化。虽然这仍然是一个完全受支持的数据结构,但在大多数情况下使用 TypedArray 就足够了。

This API allocates a node::Buffer object and initializes it with data copied from the passed-in buffer. While this is still a fully-supported data structure, in most cases using a TypedArray will suffice.

napi_create_date#
napi_status napi_create_date(napi_env env,
                             double time,
                             napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] time:自 1970 年 1 月 1 日 UTC 以来的 ECMAScript 时间值(以毫秒为单位)。

    [in] time: ECMAScript time value in milliseconds since 01 January, 1970 UTC.

  • [out] result:代表 JavaScript Datenapi_value

    [out] result: A napi_value representing a JavaScript Date.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 不遵守闰秒;它们被忽略,因为 ECMAScript 符合 POSIX 时间规范。

This API does not observe leap seconds; they are ignored, as ECMAScript aligns with POSIX time specification.

此 API 分配一个 JavaScript Date 对象。

This API allocates a JavaScript Date object.

JavaScript Date 对象在 ECMAScript 语言规范的 第 20.3 节 中进行了描述。

JavaScript Date objects are described in Section 20.3 of the ECMAScript Language Specification.

napi_create_external#
napi_status napi_create_external(napi_env env,
                                 void* data,
                                 napi_finalize finalize_cb,
                                 void* finalize_hint,
                                 napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] data:指向外部数据的原始指针。

    [in] data: Raw pointer to the external data.

  • [in] finalize_cb:收集外部值时调用的可选回调。napi_finalize 提供了更多详细信息。

    [in] finalize_cb: Optional callback to call when the external value is being collected. napi_finalize provides more details.

  • [in] finalize_hint:在收集期间传递给最终回调的可选提示。

    [in] finalize_hint: Optional hint to pass to the finalize callback during collection.

  • [out] result:表示外部值的 napi_value

    [out] result: A napi_value representing an external value.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 分配一个附加有外部数据的 JavaScript 值。这用于通过 JavaScript 代码传递外部数据,因此稍后可以使用 napi_get_value_external 由原生代码检索。

This API allocates a JavaScript value with external data attached to it. This is used to pass external data through JavaScript code, so it can be retrieved later by native code using napi_get_value_external.

API 添加了一个 napi_finalize 回调,当刚刚创建的 JavaScript 对象被垃圾回收时将调用该回调。

The API adds a napi_finalize callback which will be called when the JavaScript object just created has been garbage collected.

创建的值不是对象,因此不支持附加属性。它被认为是一个独特的值类型:使用外部值调用 napi_typeof() 会产生 napi_external

The created value is not an object, and therefore does not support additional properties. It is considered a distinct value type: calling napi_typeof() with an external value yields napi_external.

napi_create_external_arraybuffer#
napi_status
napi_create_external_arraybuffer(napi_env env,
                                 void* external_data,
                                 size_t byte_length,
                                 napi_finalize finalize_cb,
                                 void* finalize_hint,
                                 napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] external_data:指向 ArrayBuffer 的底层字节缓冲区的指针。

    [in] external_data: Pointer to the underlying byte buffer of the ArrayBuffer.

  • [in] byte_length:底层缓冲区的字节长度。

    [in] byte_length: The length in bytes of the underlying buffer.

  • [in] finalize_cb:收集 ArrayBuffer 时调用的可选回调。napi_finalize 提供了更多详细信息。

    [in] finalize_cb: Optional callback to call when the ArrayBuffer is being collected. napi_finalize provides more details.

  • [in] finalize_hint:在收集期间传递给最终回调的可选提示。

    [in] finalize_hint: Optional hint to pass to the finalize callback during collection.

  • [out] result:代表 JavaScript ArrayBuffernapi_value

    [out] result: A napi_value representing a JavaScript ArrayBuffer.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

Node.js 以外的一些运行时已放弃对外部缓冲区的支持。在 Node.js 以外的运行时,此方法可能会返回 napi_no_external_buffers_allowed 以指示不支持外部缓冲区。如本期 electron/issues/35801 中所述,Electron 就是这样一种运行时。

Some runtimes other than Node.js have dropped support for external buffers. On runtimes other than Node.js this method may return napi_no_external_buffers_allowed to indicate that external buffers are not supported. One such runtime is Electron as described in this issue electron/issues/35801.

为了保持与所有运行时的最广泛兼容性,你可以在包含节点 API 标头之前在你的插件中定义 NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED。这样做将隐藏创建外部缓冲区的 2 个函数。如果你不小心使用其中一种方法,这将确保发生编译错误。

In order to maintain broadest compatibility with all runtimes you may define NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED in your addon before includes for the node-api headers. Doing so will hide the 2 functions that create external buffers. This will ensure a compilation error occurs if you accidentally use one of these methods.

此 API 返回对应于 JavaScript ArrayBuffer 的 Node-API 值。ArrayBuffer 的底层字节缓冲区是外部分配和管理的。调用者必须确保字节缓冲区在调用 finalize 回调之前保持有效。

This API returns a Node-API value corresponding to a JavaScript ArrayBuffer. The underlying byte buffer of the ArrayBuffer is externally allocated and managed. The caller must ensure that the byte buffer remains valid until the finalize callback is called.

API 添加了一个 napi_finalize 回调,当刚刚创建的 JavaScript 对象被垃圾回收时将调用该回调。

The API adds a napi_finalize callback which will be called when the JavaScript object just created has been garbage collected.

JavaScript ArrayBuffer 在 ECMAScript 语言规范的 第 24.1 节 中描述。

JavaScript ArrayBuffers are described in Section 24.1 of the ECMAScript Language Specification.

napi_create_external_buffer#
napi_status napi_create_external_buffer(napi_env env,
                                        size_t length,
                                        void* data,
                                        napi_finalize finalize_cb,
                                        void* finalize_hint,
                                        napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] length:输入缓冲区的大小(以字节为单位)(应与新缓冲区的大小相同)。

    [in] length: Size in bytes of the input buffer (should be the same as the size of the new buffer).

  • [in] data:指向底层缓冲区的原始指针以暴露给 JavaScript。

    [in] data: Raw pointer to the underlying buffer to expose to JavaScript.

  • [in] finalize_cb:收集 ArrayBuffer 时调用的可选回调。napi_finalize 提供了更多详细信息。

    [in] finalize_cb: Optional callback to call when the ArrayBuffer is being collected. napi_finalize provides more details.

  • [in] finalize_hint:在收集期间传递给最终回调的可选提示。

    [in] finalize_hint: Optional hint to pass to the finalize callback during collection.

  • [out] result:一个 napi_value 代表一个 node::Buffer

    [out] result: A napi_value representing a node::Buffer.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

Node.js 以外的一些运行时已放弃对外部缓冲区的支持。在 Node.js 以外的运行时,此方法可能会返回 napi_no_external_buffers_allowed 以指示不支持外部缓冲区。如本期 electron/issues/35801 中所述,Electron 就是这样一种运行时。

Some runtimes other than Node.js have dropped support for external buffers. On runtimes other than Node.js this method may return napi_no_external_buffers_allowed to indicate that external buffers are not supported. One such runtime is Electron as described in this issue electron/issues/35801.

为了保持与所有运行时的最广泛兼容性,你可以在包含节点 API 标头之前在你的插件中定义 NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED。这样做将隐藏创建外部缓冲区的 2 个函数。如果你不小心使用其中一种方法,这将确保发生编译错误。

In order to maintain broadest compatibility with all runtimes you may define NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED in your addon before includes for the node-api headers. Doing so will hide the 2 functions that create external buffers. This will ensure a compilation error occurs if you accidentally use one of these methods.

此 API 分配一个 node::Buffer 对象并使用传入缓冲区支持的数据对其进行初始化。虽然这仍然是一个完全受支持的数据结构,但在大多数情况下使用 TypedArray 就足够了。

This API allocates a node::Buffer object and initializes it with data backed by the passed in buffer. While this is still a fully-supported data structure, in most cases using a TypedArray will suffice.

API 添加了一个 napi_finalize 回调,当刚刚创建的 JavaScript 对象被垃圾回收时将调用该回调。

The API adds a napi_finalize callback which will be called when the JavaScript object just created has been garbage collected.

对于 Node.js >=4 BuffersUint8Array

For Node.js >=4 Buffers are Uint8Arrays.

napi_create_object#
napi_status napi_create_object(napi_env env, napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [out] result:代表 JavaScript Objectnapi_value

    [out] result: A napi_value representing a JavaScript Object.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 分配默认的 JavaScript Object。它相当于在 JavaScript 中执行 new Object()

This API allocates a default JavaScript Object. It is the equivalent of doing new Object() in JavaScript.

JavaScript Object 类型在 ECMAScript 语言规范的 第 6.1.7 节 中进行了描述。

The JavaScript Object type is described in Section 6.1.7 of the ECMAScript Language Specification.

napi_create_symbol#
napi_status napi_create_symbol(napi_env env,
                               napi_value description,
                               napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] description:可选的 napi_value,它指的是要设置为符号描述的 JavaScript string

    [in] description: Optional napi_value which refers to a JavaScript string to be set as the description for the symbol.

  • [out] result:代表 JavaScript symbolnapi_value

    [out] result: A napi_value representing a JavaScript symbol.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 从 UTF8 编码的 C 字符串创建 JavaScript symbol 值。

This API creates a JavaScript symbol value from a UTF8-encoded C string.

JavaScript symbol 类型在 ECMAScript 语言规范的 第 19.4 节 中进行了描述。

The JavaScript symbol type is described in Section 19.4 of the ECMAScript Language Specification.

node_api_symbol_for#
napi_status node_api_symbol_for(napi_env env,
                                const char* utf8description,
                                size_t length,
                                napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] utf8description:UTF-8 C 字符串,表示用作符号描述的文本。

    [in] utf8description: UTF-8 C string representing the text to be used as the description for the symbol.

  • [in] length:描述字符串的长度(以字节为单位),如果它以 null 结尾则为 NAPI_AUTO_LENGTH

    [in] length: The length of the description string in bytes, or NAPI_AUTO_LENGTH if it is null-terminated.

  • [out] result:代表 JavaScript symbolnapi_value

    [out] result: A napi_value representing a JavaScript symbol.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 在全局注册表中搜索具有给定描述的现有符号。如果该符号已经存在,它将被返回,否则将在注册表中创建一个新符号。

This API searches in the global registry for an existing symbol with the given description. If the symbol already exists it will be returned, otherwise a new symbol will be created in the registry.

JavaScript symbol 类型在 ECMAScript 语言规范的 第 19.4 节 中进行了描述。

The JavaScript symbol type is described in Section 19.4 of the ECMAScript Language Specification.

napi_create_typedarray#
napi_status napi_create_typedarray(napi_env env,
                                   napi_typedarray_type type,
                                   size_t length,
                                   napi_value arraybuffer,
                                   size_t byte_offset,
                                   napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] typeTypedArray 中元素的标量数据类型。

    [in] type: Scalar datatype of the elements within the TypedArray.

  • [in] lengthTypedArray 中的元素数。

    [in] length: Number of elements in the TypedArray.

  • [in] arraybufferArrayBuffer 是类型化数组的基础。

    [in] arraybuffer: ArrayBuffer underlying the typed array.

  • [in] byte_offsetArrayBuffer 中开始投影 TypedArray 的字节偏移量。

    [in] byte_offset: The byte offset within the ArrayBuffer from which to start projecting the TypedArray.

  • [out] result:代表 JavaScript TypedArraynapi_value

    [out] result: A napi_value representing a JavaScript TypedArray.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 在现有的 ArrayBuffer 上创建一个 JavaScript TypedArray 对象。TypedArray 对象在底层数据缓冲区上提供类似数组的视图,其中每个元素都具有相同的底层二进制标量数据类型。

This API creates a JavaScript TypedArray object over an existing ArrayBuffer. TypedArray objects provide an array-like view over an underlying data buffer where each element has the same underlying binary scalar datatype.

要求 (length * size_of_element) + byte_offset 应该 <= 传入数组的大小(以字节为单位)。如果不是,则引发 RangeError 异常。

It's required that (length * size_of_element) + byte_offset should be <= the size in bytes of the array passed in. If not, a RangeError exception is raised.

JavaScript TypedArray 对象在 ECMAScript 语言规范的 第 22.2 节 中进行了描述。

JavaScript TypedArray objects are described in Section 22.2 of the ECMAScript Language Specification.

napi_create_dataview#
napi_status napi_create_dataview(napi_env env,
                                 size_t byte_length,
                                 napi_value arraybuffer,
                                 size_t byte_offset,
                                 napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] lengthDataView 中的元素数。

    [in] length: Number of elements in the DataView.

  • [in] arraybufferArrayBufferDataView 的基础。

    [in] arraybuffer: ArrayBuffer underlying the DataView.

  • [in] byte_offsetArrayBuffer 中开始投影 DataView 的字节偏移量。

    [in] byte_offset: The byte offset within the ArrayBuffer from which to start projecting the DataView.

  • [out] result:代表 JavaScript DataViewnapi_value

    [out] result: A napi_value representing a JavaScript DataView.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 在现有的 ArrayBuffer 上创建一个 JavaScript DataView 对象。DataView 对象在底层数据缓冲区上提供类似数组的视图,但在 ArrayBuffer 中允许不同大小和类型的项目。

This API creates a JavaScript DataView object over an existing ArrayBuffer. DataView objects provide an array-like view over an underlying data buffer, but one which allows items of different size and type in the ArrayBuffer.

要求 byte_length + byte_offset 小于或等于传入数组的字节大小。如果不是,则引发 RangeError 异常。

It is required that byte_length + byte_offset is less than or equal to the size in bytes of the array passed in. If not, a RangeError exception is raised.

JavaScript DataView 对象在 ECMAScript 语言规范的 第 24.3 节 中进行了描述。

JavaScript DataView objects are described in Section 24.3 of the ECMAScript Language Specification.

从 C 类型转换为 Node-API 的函数#

Functions to convert from C types to Node-API

napi_create_int32#
napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要在 JavaScript 中表示的整数值。

    [in] value: Integer value to be represented in JavaScript.

  • [out] result:代表 JavaScript numbernapi_value

    [out] result: A napi_value representing a JavaScript number.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 用于将 C int32_t 类型转换为 JavaScript number 类型。

This API is used to convert from the C int32_t type to the JavaScript number type.

JavaScript number 类型在 ECMAScript 语言规范的 第 6.1.6 节 中进行了描述。

The JavaScript number type is described in Section 6.1.6 of the ECMAScript Language Specification.

napi_create_uint32#
napi_status napi_create_uint32(napi_env env, uint32_t value, napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要在 JavaScript 中表示的无符号整数值。

    [in] value: Unsigned integer value to be represented in JavaScript.

  • [out] result:代表 JavaScript numbernapi_value

    [out] result: A napi_value representing a JavaScript number.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 用于将 C uint32_t 类型转换为 JavaScript number 类型。

This API is used to convert from the C uint32_t type to the JavaScript number type.

JavaScript number 类型在 ECMAScript 语言规范的 第 6.1.6 节 中进行了描述。

The JavaScript number type is described in Section 6.1.6 of the ECMAScript Language Specification.

napi_create_int64#
napi_status napi_create_int64(napi_env env, int64_t value, napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要在 JavaScript 中表示的整数值。

    [in] value: Integer value to be represented in JavaScript.

  • [out] result:代表 JavaScript numbernapi_value

    [out] result: A napi_value representing a JavaScript number.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 用于将 C int64_t 类型转换为 JavaScript number 类型。

This API is used to convert from the C int64_t type to the JavaScript number type.

JavaScript number 类型在 ECMAScript 语言规范的 第 6.1.6 节 中进行了描述。请注意,无法在 JavaScript 中完全精确地表示 int64_t 的完整范围。超出 Number.MIN_SAFE_INTEGER -(2**53 - 1) 范围的整数值 - Number.MAX_SAFE_INTEGER (2**53 - 1) 将失去精度。

The JavaScript number type is described in Section 6.1.6 of the ECMAScript Language Specification. Note the complete range of int64_t cannot be represented with full precision in JavaScript. Integer values outside the range of Number.MIN_SAFE_INTEGER -(2**53 - 1) - Number.MAX_SAFE_INTEGER (2**53 - 1) will lose precision.

napi_create_double#
napi_status napi_create_double(napi_env env, double value, napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要在 JavaScript 中表示的双精度值。

    [in] value: Double-precision value to be represented in JavaScript.

  • [out] result:代表 JavaScript numbernapi_value

    [out] result: A napi_value representing a JavaScript number.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 用于将 C double 类型转换为 JavaScript number 类型。

This API is used to convert from the C double type to the JavaScript number type.

JavaScript number 类型在 ECMAScript 语言规范的 第 6.1.6 节 中进行了描述。

The JavaScript number type is described in Section 6.1.6 of the ECMAScript Language Specification.

napi_create_bigint_int64#
napi_status napi_create_bigint_int64(napi_env env,
                                     int64_t value,
                                     napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要在 JavaScript 中表示的整数值。

    [in] value: Integer value to be represented in JavaScript.

  • [out] result:代表 JavaScript BigIntnapi_value

    [out] result: A napi_value representing a JavaScript BigInt.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 将 C int64_t 类型转换为 JavaScript BigInt 类型。

This API converts the C int64_t type to the JavaScript BigInt type.

napi_create_bigint_uint64#
napi_status napi_create_bigint_uint64(napi_env env,
                                      uint64_t value,
                                      napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要在 JavaScript 中表示的无符号整数值。

    [in] value: Unsigned integer value to be represented in JavaScript.

  • [out] result:代表 JavaScript BigIntnapi_value

    [out] result: A napi_value representing a JavaScript BigInt.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 将 C uint64_t 类型转换为 JavaScript BigInt 类型。

This API converts the C uint64_t type to the JavaScript BigInt type.

napi_create_bigint_words#
napi_status napi_create_bigint_words(napi_env env,
                                     int sign_bit,
                                     size_t word_count,
                                     const uint64_t* words,
                                     napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] sign_bit:确定生成的 BigInt 是正数还是负数。

    [in] sign_bit: Determines if the resulting BigInt will be positive or negative.

  • [in] word_countwords 数组的长度。

    [in] word_count: The length of the words array.

  • [in] wordsuint64_t little-endian 64 位字数组。

    [in] words: An array of uint64_t little-endian 64-bit words.

  • [out] result:代表 JavaScript BigIntnapi_value

    [out] result: A napi_value representing a JavaScript BigInt.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 将一组无符号 64 位字转换为单个 BigInt 值。

This API converts an array of unsigned 64-bit words into a single BigInt value.

生成的 BigInt 计算如下:(–1)sign_bit (words[0] × (264)0 + words[1] × (264)1 + …)

The resulting BigInt is calculated as: (–1)sign_bit (words[0] × (264)0 + words[1] × (264)1 + …)

napi_create_string_latin1#
napi_status napi_create_string_latin1(napi_env env,
                                      const char* str,
                                      size_t length,
                                      napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] str:表示 ISO-8859-1 编码字符串的字符缓冲区。

    [in] str: Character buffer representing an ISO-8859-1-encoded string.

  • [in] length:字符串的长度(以字节为单位),如果它以 null 结尾则为 NAPI_AUTO_LENGTH

    [in] length: The length of the string in bytes, or NAPI_AUTO_LENGTH if it is null-terminated.

  • [out] result:代表 JavaScript stringnapi_value

    [out] result: A napi_value representing a JavaScript string.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 从 ISO-8859-1 编码的 C 字符串创建一个 JavaScript string 值。复制原生字符串。

This API creates a JavaScript string value from an ISO-8859-1-encoded C string. The native string is copied.

JavaScript string 类型在 ECMAScript 语言规范的 第 6.1.4 节 中进行了描述。

The JavaScript string type is described in Section 6.1.4 of the ECMAScript Language Specification.

node_api_create_external_string_latin1#

稳定性: 1 - 实验性的

Stability: 1 - Experimental

napi_status
node_api_create_external_string_latin1(napi_env env,
                                       char* str,
                                       size_t length,
                                       napi_finalize finalize_callback,
                                       void* finalize_hint,
                                       napi_value* result,
                                       bool* copied); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] str:表示 ISO-8859-1 编码字符串的字符缓冲区。

    [in] str: Character buffer representing an ISO-8859-1-encoded string.

  • [in] length:字符串的长度(以字节为单位),如果它以 null 结尾则为 NAPI_AUTO_LENGTH

    [in] length: The length of the string in bytes, or NAPI_AUTO_LENGTH if it is null-terminated.

  • [in] finalize_callback:收集字符串时调用的函数。该函数将使用以下参数调用:

    [in] finalize_callback: The function to call when the string is being collected. The function will be called with the following parameters:

    • [in] env:加载项运行的环境。如果字符串是作为工作线程或主 Node.js 实例终止的一部分而被收集的,则该值可能为 null。

      [in] env: The environment in which the add-on is running. This value may be null if the string is being collected as part of the termination of the worker or the main Node.js instance.

    • [in] data:这是作为 void* 指针的值 str

      [in] data: This is the value str as a void* pointer.

    • [in] finalize_hint:这是赋予 API 的值 finalize_hintnapi_finalize 提供了更多详细信息。该参数是可选的。传递 null 值意味着在收集相应的 JavaScript 字符串时不需要通知加载项。

      [in] finalize_hint: This is the value finalize_hint that was given to the API. napi_finalize provides more details. This parameter is optional. Passing a null value means that the add-on doesn't need to be notified when the corresponding JavaScript string is collected.

  • [in] finalize_hint:在收集期间传递给最终回调的可选提示。

    [in] finalize_hint: Optional hint to pass to the finalize callback during collection.

  • [out] result:代表 JavaScript stringnapi_value

    [out] result: A napi_value representing a JavaScript string.

  • [out] copied:字符串是否被复制。如果是,则终结器将已被调用来销毁 str

    [out] copied: Whether the string was copied. If it was, the finalizer will already have been invoked to destroy str.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 从 ISO-8859-1 编码的 C 字符串创建一个 JavaScript string 值。原生字符串不能被复制,因此必须在 JavaScript 值的整个生命周期中存在。

This API creates a JavaScript string value from an ISO-8859-1-encoded C string. The native string may not be copied and must thus exist for the entire life cycle of the JavaScript value.

JavaScript string 类型在 ECMAScript 语言规范的 第 6.1.4 节 中进行了描述。

The JavaScript string type is described in Section 6.1.4 of the ECMAScript Language Specification.

napi_create_string_utf16#
napi_status napi_create_string_utf16(napi_env env,
                                     const char16_t* str,
                                     size_t length,
                                     napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] str:表示 UTF16-LE 编码字符串的字符缓冲区。

    [in] str: Character buffer representing a UTF16-LE-encoded string.

  • [in] length:以两字节代码单元表示的字符串长度,如果它以 null 终止,则为 NAPI_AUTO_LENGTH

    [in] length: The length of the string in two-byte code units, or NAPI_AUTO_LENGTH if it is null-terminated.

  • [out] result:代表 JavaScript stringnapi_value

    [out] result: A napi_value representing a JavaScript string.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 从 UTF16-LE 编码的 C 字符串创建 JavaScript string 值。复制原生字符串。

This API creates a JavaScript string value from a UTF16-LE-encoded C string. The native string is copied.

JavaScript string 类型在 ECMAScript 语言规范的 第 6.1.4 节 中进行了描述。

The JavaScript string type is described in Section 6.1.4 of the ECMAScript Language Specification.

node_api_create_external_string_utf16#

稳定性: 1 - 实验性的

Stability: 1 - Experimental

napi_status
node_api_create_external_string_utf16(napi_env env,
                                      char16_t* str,
                                      size_t length,
                                      napi_finalize finalize_callback,
                                      void* finalize_hint,
                                      napi_value* result,
                                      bool* copied); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] str:表示 UTF16-LE 编码字符串的字符缓冲区。

    [in] str: Character buffer representing a UTF16-LE-encoded string.

  • [in] length:以两字节代码单元表示的字符串长度,如果它以 null 终止,则为 NAPI_AUTO_LENGTH

    [in] length: The length of the string in two-byte code units, or NAPI_AUTO_LENGTH if it is null-terminated.

  • [in] finalize_callback:收集字符串时调用的函数。该函数将使用以下参数调用:

    [in] finalize_callback: The function to call when the string is being collected. The function will be called with the following parameters:

    • [in] env:加载项运行的环境。如果字符串是作为工作线程或主 Node.js 实例终止的一部分而被收集的,则该值可能为 null。

      [in] env: The environment in which the add-on is running. This value may be null if the string is being collected as part of the termination of the worker or the main Node.js instance.

    • [in] data:这是作为 void* 指针的值 str

      [in] data: This is the value str as a void* pointer.

    • [in] finalize_hint:这是赋予 API 的值 finalize_hintnapi_finalize 提供了更多详细信息。该参数是可选的。传递 null 值意味着在收集相应的 JavaScript 字符串时不需要通知加载项。

      [in] finalize_hint: This is the value finalize_hint that was given to the API. napi_finalize provides more details. This parameter is optional. Passing a null value means that the add-on doesn't need to be notified when the corresponding JavaScript string is collected.

  • [in] finalize_hint:在收集期间传递给最终回调的可选提示。

    [in] finalize_hint: Optional hint to pass to the finalize callback during collection.

  • [out] result:代表 JavaScript stringnapi_value

    [out] result: A napi_value representing a JavaScript string.

  • [out] copied:字符串是否被复制。如果是,则终结器将已被调用来销毁 str

    [out] copied: Whether the string was copied. If it was, the finalizer will already have been invoked to destroy str.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 从 UTF16-LE 编码的 C 字符串创建 JavaScript string 值。原生字符串不能被复制,因此必须在 JavaScript 值的整个生命周期中存在。

This API creates a JavaScript string value from a UTF16-LE-encoded C string. The native string may not be copied and must thus exist for the entire life cycle of the JavaScript value.

JavaScript string 类型在 ECMAScript 语言规范的 第 6.1.4 节 中进行了描述。

The JavaScript string type is described in Section 6.1.4 of the ECMAScript Language Specification.

napi_create_string_utf8#
napi_status napi_create_string_utf8(napi_env env,
                                    const char* str,
                                    size_t length,
                                    napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] str:表示 UTF8 编码字符串的字符缓冲区。

    [in] str: Character buffer representing a UTF8-encoded string.

  • [in] length:字符串的长度(以字节为单位),如果它以 null 结尾则为 NAPI_AUTO_LENGTH

    [in] length: The length of the string in bytes, or NAPI_AUTO_LENGTH if it is null-terminated.

  • [out] result:代表 JavaScript stringnapi_value

    [out] result: A napi_value representing a JavaScript string.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 从 UTF8 编码的 C 字符串创建 JavaScript string 值。复制原生字符串。

This API creates a JavaScript string value from a UTF8-encoded C string. The native string is copied.

JavaScript string 类型在 ECMAScript 语言规范的 第 6.1.4 节 中进行了描述。

The JavaScript string type is described in Section 6.1.4 of the ECMAScript Language Specification.

从 Node-API 转换为 C 类型的函数#

Functions to convert from Node-API to C types

napi_get_array_length#
napi_status napi_get_array_length(napi_env env,
                                  napi_value value,
                                  uint32_t* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] valuenapi_value 代表查询长度的 JavaScript Array

    [in] value: napi_value representing the JavaScript Array whose length is being queried.

  • [out] resultuint32 代表数组的长度。

    [out] result: uint32 representing length of the array.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 返回数组的长度。

This API returns the length of an array.

Array 长度在 ECMAScript 语言规范的 第 22.1.4.1 节 中描述。

Array length is described in Section 22.1.4.1 of the ECMAScript Language Specification.

napi_get_arraybuffer_info#
napi_status napi_get_arraybuffer_info(napi_env env,
                                      napi_value arraybuffer,
                                      void** data,
                                      size_t* byte_length) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] arraybuffernapi_value 代表被查询的 ArrayBuffer

    [in] arraybuffer: napi_value representing the ArrayBuffer being queried.

  • [out] dataArrayBuffer 的底层数据缓冲区。如果 byte_length 是 0,则这可能是 NULL 或任何其他指针值。

    [out] data: The underlying data buffer of the ArrayBuffer. If byte_length is 0, this may be NULL or any other pointer value.

  • [out] byte_length:底层数据缓冲区的字节长度。

    [out] byte_length: Length in bytes of the underlying data buffer.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 用于检索 ArrayBuffer 的底层数据缓冲区及其长度。

This API is used to retrieve the underlying data buffer of an ArrayBuffer and its length.

WARNING:使用此 API 时要小心。底层数据缓冲区的生命周期由 ArrayBuffer 管理,即使在返回后也是如此。使用此 API 的一种可能的安全方法是与 napi_create_reference 结合使用,它可用于保证对 ArrayBuffer 生命周期的控制。只要没有对可能触发 GC 的其他 API 的调用,在同一回调中使用返回的数据缓冲区也是安全的。

WARNING: Use caution while using this API. The lifetime of the underlying data buffer is managed by the ArrayBuffer even after it's returned. A possible safe way to use this API is in conjunction with napi_create_reference, which can be used to guarantee control over the lifetime of the ArrayBuffer. It's also safe to use the returned data buffer within the same callback as long as there are no calls to other APIs that might trigger a GC.

napi_get_buffer_info#
napi_status napi_get_buffer_info(napi_env env,
                                 napi_value value,
                                 void** data,
                                 size_t* length) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] valuenapi_value 代表正在查询的 node::BufferUint8Array

    [in] value: napi_value representing the node::Buffer or Uint8Array being queried.

  • [out] datanode::BufferUint8Array 的底层数据缓冲区。如果长度是 0,这可能是 NULL 或任何其他指针值。

    [out] data: The underlying data buffer of the node::Buffer or Uint8Array. If length is 0, this may be NULL or any other pointer value.

  • [out] length:底层数据缓冲区的字节长度。

    [out] length: Length in bytes of the underlying data buffer.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此方法返回与 napi_get_typedarray_info 相同的 databyte_lengthnapi_get_typedarray_info 也接受 node::Buffer (Uint8Array)作为值。

This method returns the identical data and byte_length as napi_get_typedarray_info. And napi_get_typedarray_info accepts a node::Buffer (a Uint8Array) as the value too.

此 API 用于检索 node::Buffer 的底层数据缓冲区及其长度。

This API is used to retrieve the underlying data buffer of a node::Buffer and its length.

警告:使用此 API 时要小心,因为如果底层数据缓冲区由 VM 管理,则无法保证其生命周期。

Warning: Use caution while using this API since the underlying data buffer's lifetime is not guaranteed if it's managed by the VM.

napi_get_prototype#
napi_status napi_get_prototype(napi_env env,
                               napi_value object,
                               napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] objectnapi_value 表示要返回其原型的 JavaScript Object。这将返回 Object.getPrototypeOf 的等价物(与函数的 prototype 属性不同)。

    [in] object: napi_value representing JavaScript Object whose prototype to return. This returns the equivalent of Object.getPrototypeOf (which is not the same as the function's prototype property).

  • [out] resultnapi_value 表示给定对象的原型。

    [out] result: napi_value representing prototype of the given object.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

napi_get_typedarray_info#
napi_status napi_get_typedarray_info(napi_env env,
                                     napi_value typedarray,
                                     napi_typedarray_type* type,
                                     size_t* length,
                                     void** data,
                                     napi_value* arraybuffer,
                                     size_t* byte_offset) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] typedarraynapi_value 表示要查询其属性的 TypedArray

    [in] typedarray: napi_value representing the TypedArray whose properties to query.

  • [out] typeTypedArray 中元素的标量数据类型。

    [out] type: Scalar datatype of the elements within the TypedArray.

  • [out] lengthTypedArray 中的元素数。

    [out] length: The number of elements in the TypedArray.

  • [out] dataTypedArray 底层的数据缓冲区由 byte_offset 值调整,使其指向 TypedArray 中的第一个元素。如果数组的长度是 0,这可能是 NULL 或任何其他指针值。

    [out] data: The data buffer underlying the TypedArray adjusted by the byte_offset value so that it points to the first element in the TypedArray. If the length of the array is 0, this may be NULL or any other pointer value.

  • [out] arraybufferTypedArray 下的 ArrayBuffer

    [out] arraybuffer: The ArrayBuffer underlying the TypedArray.

  • [out] byte_offset:数组的第一个元素所在的基础原生数组中的字节偏移量。data 参数的值已经过调整,因此 data 指向数组中的第一个元素。因此,原生数组的第一个字节将位于 data - byte_offset

    [out] byte_offset: The byte offset within the underlying native array at which the first element of the arrays is located. The value for the data parameter has already been adjusted so that data points to the first element in the array. Therefore, the first byte of the native array would be at data - byte_offset.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 返回类型化数组的各种属性。

This API returns various properties of a typed array.

如果不需要该属性,则任何输出参数都可以是 NULL

Any of the out parameters may be NULL if that property is unneeded.

警告:使用此 API 时要小心,因为底层数据缓冲区由 VM 管理。

Warning: Use caution while using this API since the underlying data buffer is managed by the VM.

napi_get_dataview_info#
napi_status napi_get_dataview_info(napi_env env,
                                   napi_value dataview,
                                   size_t* byte_length,
                                   void** data,
                                   napi_value* arraybuffer,
                                   size_t* byte_offset) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] dataviewnapi_value 表示要查询其属性的 DataView

    [in] dataview: napi_value representing the DataView whose properties to query.

  • [out] byte_lengthDataView 中的字节数。

    [out] byte_length: Number of bytes in the DataView.

  • [out] dataDataView 下的数据缓冲区。如果 byte_length 是 0,则这可能是 NULL 或任何其他指针值。

    [out] data: The data buffer underlying the DataView. If byte_length is 0, this may be NULL or any other pointer value.

  • [out] arraybufferArrayBufferDataView 的基础。

    [out] arraybuffer: ArrayBuffer underlying the DataView.

  • [out] byte_offset:开始投影 DataView 的数据缓冲区中的字节偏移量。

    [out] byte_offset: The byte offset within the data buffer from which to start projecting the DataView.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

如果不需要该属性,则任何输出参数都可以是 NULL

Any of the out parameters may be NULL if that property is unneeded.

此 API 返回 DataView 的各种属性。

This API returns various properties of a DataView.

napi_get_date_value#
napi_status napi_get_date_value(napi_env env,
                                napi_value value,
                                double* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] valuenapi_value 代表一个 JavaScript Date

    [in] value: napi_value representing a JavaScript Date.

  • [out] result:作为 double 的时间值表示为自 1970 年 1 月 1 日 UTC 午夜以来的毫秒数。

    [out] result: Time value as a double represented as milliseconds since midnight at the beginning of 01 January, 1970 UTC.

此 API 不遵守闰秒;它们被忽略,因为 ECMAScript 符合 POSIX 时间规范。

This API does not observe leap seconds; they are ignored, as ECMAScript aligns with POSIX time specification.

如果 API 成功,则返回 napi_ok。如果传入非日期 napi_value,则返回 napi_date_expected

Returns napi_ok if the API succeeded. If a non-date napi_value is passed in it returns napi_date_expected.

此 API 返回给定 JavaScript Date 的时间值的 C 双精度基础类型。

This API returns the C double primitive of time value for the given JavaScript Date.

napi_get_value_bool#
napi_status napi_get_value_bool(napi_env env, napi_value value, bool* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] valuenapi_value 代表 JavaScript Boolean

    [in] value: napi_value representing JavaScript Boolean.

  • [out] result:给定 JavaScript Boolean 的 C 布尔基础类型等价物。

    [out] result: C boolean primitive equivalent of the given JavaScript Boolean.

如果 API 成功,则返回 napi_ok。如果传入非布尔值 napi_value,则返回 napi_boolean_expected

Returns napi_ok if the API succeeded. If a non-boolean napi_value is passed in it returns napi_boolean_expected.

此 API 返回给定 JavaScript Boolean 的 C 布尔基础类型等价物。

This API returns the C boolean primitive equivalent of the given JavaScript Boolean.

napi_get_value_double#
napi_status napi_get_value_double(napi_env env,
                                  napi_value value,
                                  double* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] valuenapi_value 代表 JavaScript number

    [in] value: napi_value representing JavaScript number.

  • [out] result:给定的 JavaScript number 的 C 双精度基础类型等价物。

    [out] result: C double primitive equivalent of the given JavaScript number.

如果 API 成功,则返回 napi_ok。如果传入非数字 napi_value,则返回 napi_number_expected

Returns napi_ok if the API succeeded. If a non-number napi_value is passed in it returns napi_number_expected.

此 API 返回给定 JavaScript number 的 C 双精度基础类型等价物。

This API returns the C double primitive equivalent of the given JavaScript number.

napi_get_value_bigint_int64#
napi_status napi_get_value_bigint_int64(napi_env env,
                                        napi_value value,
                                        int64_t* result,
                                        bool* lossless); 
  • [in] env:调用 API 的环境

    [in] env: The environment that the API is invoked under

  • [in] valuenapi_value 代表 JavaScript BigInt

    [in] value: napi_value representing JavaScript BigInt.

  • [out] result:给定的 JavaScript BigInt 的 C int64_t 基础类型等价物。

    [out] result: C int64_t primitive equivalent of the given JavaScript BigInt.

  • [out] lossless:指示 BigInt 值是否已无损转换。

    [out] lossless: Indicates whether the BigInt value was converted losslessly.

如果 API 成功,则返回 napi_ok。如果传入非 BigInt,则返回 napi_bigint_expected

Returns napi_ok if the API succeeded. If a non-BigInt is passed in it returns napi_bigint_expected.

此 API 返回给定 JavaScript BigInt 的 C int64_t 基础类型等价物。如果需要,它将截断该值,将 lossless 设置为 false

This API returns the C int64_t primitive equivalent of the given JavaScript BigInt. If needed it will truncate the value, setting lossless to false.

napi_get_value_bigint_uint64#
napi_status napi_get_value_bigint_uint64(napi_env env,
                                        napi_value value,
                                        uint64_t* result,
                                        bool* lossless); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] valuenapi_value 代表 JavaScript BigInt

    [in] value: napi_value representing JavaScript BigInt.

  • [out] result:给定的 JavaScript BigInt 的 C uint64_t 基础类型等价物。

    [out] result: C uint64_t primitive equivalent of the given JavaScript BigInt.

  • [out] lossless:指示 BigInt 值是否已无损转换。

    [out] lossless: Indicates whether the BigInt value was converted losslessly.

如果 API 成功,则返回 napi_ok。如果传入非 BigInt,则返回 napi_bigint_expected

Returns napi_ok if the API succeeded. If a non-BigInt is passed in it returns napi_bigint_expected.

此 API 返回给定 JavaScript BigInt 的 C uint64_t 基础类型等价物。如果需要,它将截断该值,将 lossless 设置为 false

This API returns the C uint64_t primitive equivalent of the given JavaScript BigInt. If needed it will truncate the value, setting lossless to false.

napi_get_value_bigint_words#
napi_status napi_get_value_bigint_words(napi_env env,
                                        napi_value value,
                                        int* sign_bit,
                                        size_t* word_count,
                                        uint64_t* words); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] valuenapi_value 代表 JavaScript BigInt

    [in] value: napi_value representing JavaScript BigInt.

  • [out] sign_bit:表示 JavaScript BigInt 是正数还是负数的整数。

    [out] sign_bit: Integer representing if the JavaScript BigInt is positive or negative.

  • [in/out] word_count:必须初始化为 words 数组的长度。返回时,它将被设置为存储此 BigInt 所需的实际字数。

    [in/out] word_count: Must be initialized to the length of the words array. Upon return, it will be set to the actual number of words that would be needed to store this BigInt.

  • [out] words:指向预分配的 64 位字数组的指针。

    [out] words: Pointer to a pre-allocated 64-bit word array.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 将单个 BigInt 值转换为符号位、64 位小端数组和数组中的元素数。sign_bitwords 可能都设置为 NULL,以便只得到 word_count

This API converts a single BigInt value into a sign bit, 64-bit little-endian array, and the number of elements in the array. sign_bit and words may be both set to NULL, in order to get only word_count.

napi_get_value_external#
napi_status napi_get_value_external(napi_env env,
                                    napi_value value,
                                    void** result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] valuenapi_value 代表 JavaScript 外部值。

    [in] value: napi_value representing JavaScript external value.

  • [out] result:指向由 JavaScript 外部值封装的数据的指针。

    [out] result: Pointer to the data wrapped by the JavaScript external value.

如果 API 成功,则返回 napi_ok。如果传入非外部 napi_value,则返回 napi_invalid_arg

Returns napi_ok if the API succeeded. If a non-external napi_value is passed in it returns napi_invalid_arg.

此 API 检索先前传递给 napi_create_external() 的外部数据指针。

This API retrieves the external data pointer that was previously passed to napi_create_external().

napi_get_value_int32#
napi_status napi_get_value_int32(napi_env env,
                                 napi_value value,
                                 int32_t* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] valuenapi_value 代表 JavaScript number

    [in] value: napi_value representing JavaScript number.

  • [out] result:给定的 JavaScript number 的 C int32 基础类型等价物。

    [out] result: C int32 primitive equivalent of the given JavaScript number.

如果 API 成功,则返回 napi_ok。如果在 napi_number_expected 中传递了非数字 napi_value

Returns napi_ok if the API succeeded. If a non-number napi_value is passed in napi_number_expected.

此 API 返回给定 JavaScript number 的 C int32 基础类型等价物。

This API returns the C int32 primitive equivalent of the given JavaScript number.

如果该数字超出 32 位整数的范围,则结果将被截断为与底部 32 位等效的值。如果该值 > 231,这可能会导致较大的正数变成负数 - 1.

If the number exceeds the range of the 32 bit integer, then the result is truncated to the equivalent of the bottom 32 bits. This can result in a large positive number becoming a negative number if the value is > 231 - 1.

非有限数值(NaN+Infinity-Infinity)将结果设置为零。

Non-finite number values (NaN, +Infinity, or -Infinity) set the result to zero.

napi_get_value_int64#
napi_status napi_get_value_int64(napi_env env,
                                 napi_value value,
                                 int64_t* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] valuenapi_value 代表 JavaScript number

    [in] value: napi_value representing JavaScript number.

  • [out] result:给定的 JavaScript number 的 C int64 基础类型等价物。

    [out] result: C int64 primitive equivalent of the given JavaScript number.

如果 API 成功,则返回 napi_ok。如果传入非数字 napi_value,则返回 napi_number_expected

Returns napi_ok if the API succeeded. If a non-number napi_value is passed in it returns napi_number_expected.

此 API 返回给定 JavaScript number 的 C int64 基础类型等价物。

This API returns the C int64 primitive equivalent of the given JavaScript number.

number 值超出 Number.MIN_SAFE_INTEGER -(2**53 - 1) 范围 - Number.MAX_SAFE_INTEGER (2**53 - 1) 将失去精度。

number values outside the range of Number.MIN_SAFE_INTEGER -(2**53 - 1) - Number.MAX_SAFE_INTEGER (2**53 - 1) will lose precision.

非有限数值(NaN+Infinity-Infinity)将结果设置为零。

Non-finite number values (NaN, +Infinity, or -Infinity) set the result to zero.

napi_get_value_string_latin1#
napi_status napi_get_value_string_latin1(napi_env env,
                                         napi_value value,
                                         char* buf,
                                         size_t bufsize,
                                         size_t* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] valuenapi_value 代表 JavaScript 字符串。

    [in] value: napi_value representing JavaScript string.

  • [in] buf:写入 ISO-8859-1 编码字符串的缓冲区。如果传入 NULL,则在 result 中返回以字节为单位的字符串长度,不包括空终止符。

    [in] buf: Buffer to write the ISO-8859-1-encoded string into. If NULL is passed in, the length of the string in bytes and excluding the null terminator is returned in result.

  • [in] bufsize:目标缓冲区的大小。当此值不足时,返回的字符串将被截断并以 null 终止。

    [in] bufsize: Size of the destination buffer. When this value is insufficient, the returned string is truncated and null-terminated.

  • [out] result:复制到缓冲区中的字节数,不包括空终止符。

    [out] result: Number of bytes copied into the buffer, excluding the null terminator.

如果 API 成功,则返回 napi_ok。如果传入非 string napi_value,则返回 napi_string_expected

Returns napi_ok if the API succeeded. If a non-string napi_value is passed in it returns napi_string_expected.

此 API 返回对应于传入值的 ISO-8859-1 编码字符串。

This API returns the ISO-8859-1-encoded string corresponding the value passed in.

napi_get_value_string_utf8#
napi_status napi_get_value_string_utf8(napi_env env,
                                       napi_value value,
                                       char* buf,
                                       size_t bufsize,
                                       size_t* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] valuenapi_value 代表 JavaScript 字符串。

    [in] value: napi_value representing JavaScript string.

  • [in] buf:将 UTF8 编码的字符串写入的缓冲区。如果传入 NULL,则在 result 中返回以字节为单位的字符串长度,不包括空终止符。

    [in] buf: Buffer to write the UTF8-encoded string into. If NULL is passed in, the length of the string in bytes and excluding the null terminator is returned in result.

  • [in] bufsize:目标缓冲区的大小。当此值不足时,返回的字符串将被截断并以 null 终止。

    [in] bufsize: Size of the destination buffer. When this value is insufficient, the returned string is truncated and null-terminated.

  • [out] result:复制到缓冲区中的字节数,不包括空终止符。

    [out] result: Number of bytes copied into the buffer, excluding the null terminator.

如果 API 成功,则返回 napi_ok。如果传入非 string napi_value,则返回 napi_string_expected

Returns napi_ok if the API succeeded. If a non-string napi_value is passed in it returns napi_string_expected.

此 API 返回对应于传入值的 UTF8 编码字符串。

This API returns the UTF8-encoded string corresponding the value passed in.

napi_get_value_string_utf16#
napi_status napi_get_value_string_utf16(napi_env env,
                                        napi_value value,
                                        char16_t* buf,
                                        size_t bufsize,
                                        size_t* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] valuenapi_value 代表 JavaScript 字符串。

    [in] value: napi_value representing JavaScript string.

  • [in] buf:将 UTF16-LE 编码字符串写入的缓冲区。如果传入 NULL,则返回字符串的 2 字节代码单元长度,不包括空终止符。

    [in] buf: Buffer to write the UTF16-LE-encoded string into. If NULL is passed in, the length of the string in 2-byte code units and excluding the null terminator is returned.

  • [in] bufsize:目标缓冲区的大小。当此值不足时,返回的字符串将被截断并以 null 终止。

    [in] bufsize: Size of the destination buffer. When this value is insufficient, the returned string is truncated and null-terminated.

  • [out] result:复制到缓冲区中的 2 字节代码单元数,不包括空终止符。

    [out] result: Number of 2-byte code units copied into the buffer, excluding the null terminator.

如果 API 成功,则返回 napi_ok。如果传入非 string napi_value,则返回 napi_string_expected

Returns napi_ok if the API succeeded. If a non-string napi_value is passed in it returns napi_string_expected.

此 API 返回对应于传入值的 UTF16 编码字符串。

This API returns the UTF16-encoded string corresponding the value passed in.

napi_get_value_uint32#
napi_status napi_get_value_uint32(napi_env env,
                                  napi_value value,
                                  uint32_t* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] valuenapi_value 代表 JavaScript number

    [in] value: napi_value representing JavaScript number.

  • [out] result:将给定的 napi_value 等效为 uint32_t 的 C 基础类型。

    [out] result: C primitive equivalent of the given napi_value as a uint32_t.

如果 API 成功,则返回 napi_ok。如果传入非数字 napi_value,则返回 napi_number_expected

Returns napi_ok if the API succeeded. If a non-number napi_value is passed in it returns napi_number_expected.

此 API 将给定 napi_value 的 C 基础类型等效项返回为 uint32_t

This API returns the C primitive equivalent of the given napi_value as a uint32_t.

获取全局实例的函数#

Functions to get global instances

napi_get_boolean#
napi_status napi_get_boolean(napi_env env, bool value, napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要检索的布尔值。

    [in] value: The value of the boolean to retrieve.

  • [out] resultnapi_value 表示要检索的 JavaScript Boolean 单例。

    [out] result: napi_value representing JavaScript Boolean singleton to retrieve.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 用于返回用于表示给定布尔值的 JavaScript 单例对象。

This API is used to return the JavaScript singleton object that is used to represent the given boolean value.

napi_get_global#
napi_status napi_get_global(napi_env env, napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [out] resultnapi_value 代表 JavaScript global 对象。

    [out] result: napi_value representing JavaScript global object.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 返回 global 对象。

This API returns the global object.

napi_get_null#
napi_status napi_get_null(napi_env env, napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [out] resultnapi_value 代表 JavaScript null 对象。

    [out] result: napi_value representing JavaScript null object.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 返回 null 对象。

This API returns the null object.

napi_get_undefined#
napi_status napi_get_undefined(napi_env env, napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [out] resultnapi_value 代表 JavaScript Undefined 值。

    [out] result: napi_value representing JavaScript Undefined value.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 返回 Undefined 对象。

This API returns the Undefined object.

使用 JavaScript 值和抽象操作#

Working with JavaScript values and abstract operations

Node-API 公开了一组 API 来对 JavaScript 值执行一些抽象操作。其中一些操作记录在 ECMAScript 语言规范第 7 节 下。

Node-API exposes a set of APIs to perform some abstract operations on JavaScript values. Some of these operations are documented under Section 7 of the ECMAScript Language Specification.

这些 API 支持执行以下操作之一:

These APIs support doing one of the following:

  1. 将 JavaScript 值强制转换为特定的 JavaScript 类型(例如 numberstring)。

    Coerce JavaScript values to specific JavaScript types (such as number or string).

  2. 检查 JavaScript 值的类型。

    Check the type of a JavaScript value.

  3. 检查两个 JavaScript 值之间的相等性。

    Check for equality between two JavaScript values.

napi_coerce_to_bool#

napi_status napi_coerce_to_bool(napi_env env,
                                napi_value value,
                                napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要强制转换的 JavaScript 值。

    [in] value: The JavaScript value to coerce.

  • [out] resultnapi_value 代表强制的 JavaScript Boolean

    [out] result: napi_value representing the coerced JavaScript Boolean.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 实现了 ECMAScript 语言规范的 第 7.1.2 节 中定义的抽象操作 ToBoolean()

This API implements the abstract operation ToBoolean() as defined in Section 7.1.2 of the ECMAScript Language Specification.

napi_coerce_to_number#

napi_status napi_coerce_to_number(napi_env env,
                                  napi_value value,
                                  napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要强制转换的 JavaScript 值。

    [in] value: The JavaScript value to coerce.

  • [out] resultnapi_value 代表强制的 JavaScript number

    [out] result: napi_value representing the coerced JavaScript number.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 实现了 ECMAScript 语言规范的 第 7.1.3 节 中定义的抽象操作 ToNumber()。如果传入的值是对象,此函数可能会运行 JS 代码。

This API implements the abstract operation ToNumber() as defined in Section 7.1.3 of the ECMAScript Language Specification. This function potentially runs JS code if the passed-in value is an object.

napi_coerce_to_object#

napi_status napi_coerce_to_object(napi_env env,
                                  napi_value value,
                                  napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要强制转换的 JavaScript 值。

    [in] value: The JavaScript value to coerce.

  • [out] resultnapi_value 代表强制的 JavaScript Object

    [out] result: napi_value representing the coerced JavaScript Object.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 实现了 ECMAScript 语言规范的 第 7.1.13 节 中定义的抽象操作 ToObject()

This API implements the abstract operation ToObject() as defined in Section 7.1.13 of the ECMAScript Language Specification.

napi_coerce_to_string#

napi_status napi_coerce_to_string(napi_env env,
                                  napi_value value,
                                  napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要强制转换的 JavaScript 值。

    [in] value: The JavaScript value to coerce.

  • [out] resultnapi_value 代表强制的 JavaScript string

    [out] result: napi_value representing the coerced JavaScript string.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 实现了 ECMAScript 语言规范的 第 7.1.13 节 中定义的抽象操作 ToString()。如果传入的值是对象,此函数可能会运行 JS 代码。

This API implements the abstract operation ToString() as defined in Section 7.1.13 of the ECMAScript Language Specification. This function potentially runs JS code if the passed-in value is an object.

napi_typeof#

napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要查询其类型的 JavaScript 值。

    [in] value: The JavaScript value whose type to query.

  • [out] result:JavaScript 值的类型。

    [out] result: The type of the JavaScript value.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

  • 如果 value 的类型不是已知的 ECMAScript 类型并且 value 不是外部值,则为 napi_invalid_arg

    napi_invalid_arg if the type of value is not a known ECMAScript type and value is not an External value.

此 API 表示类似于在 ECMAScript 语言规范的 第 12.5.5 节 中定义的对象上调用 typeof 运算符的行为。但是,存在一些差异:

This API represents behavior similar to invoking the typeof Operator on the object as defined in Section 12.5.5 of the ECMAScript Language Specification. However, there are some differences:

  1. 它支持检测外部值。

    It has support for detecting an External value.

  2. 它将 null 检测为单独的类型,而 ECMAScript typeof 将检测 object

    It detects null as a separate type, while ECMAScript typeof would detect object.

如果 value 的类型无效,则返回错误。

If value has a type that is invalid, an error is returned.

napi_instanceof#

napi_status napi_instanceof(napi_env env,
                            napi_value object,
                            napi_value constructor,
                            bool* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] object:要检查的 JavaScript 值。

    [in] object: The JavaScript value to check.

  • [in] constructor:要检查的构造函数的 JavaScript 函数对象。

    [in] constructor: The JavaScript function object of the constructor function to check against.

  • [out] result:如果 object instanceof constructor 为 true,则设置为 true 的布尔值。

    [out] result: Boolean that is set to true if object instanceof constructor is true.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 代表在 ECMAScript 语言规范的 第 12.10.4 节 中定义的对象上调用 instanceof 运算符。

This API represents invoking the instanceof Operator on the object as defined in Section 12.10.4 of the ECMAScript Language Specification.

napi_is_array#

napi_status napi_is_array(napi_env env, napi_value value, bool* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要检查的 JavaScript 值。

    [in] value: The JavaScript value to check.

  • [out] result:给定对象是否为数组。

    [out] result: Whether the given object is an array.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 表示调用对象上的 IsArray 操作,如 ECMAScript 语言规范的 第 7.2.2 节 中所定义。

This API represents invoking the IsArray operation on the object as defined in Section 7.2.2 of the ECMAScript Language Specification.

napi_is_arraybuffer#

napi_status napi_is_arraybuffer(napi_env env, napi_value value, bool* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要检查的 JavaScript 值。

    [in] value: The JavaScript value to check.

  • [out] result:给定对象是否为 ArrayBuffer

    [out] result: Whether the given object is an ArrayBuffer.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 检查传入的 Object 是否为数组缓冲区。

This API checks if the Object passed in is an array buffer.

napi_is_buffer#

napi_status napi_is_buffer(napi_env env, napi_value value, bool* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要检查的 JavaScript 值。

    [in] value: The JavaScript value to check.

  • [out] result:给定的 napi_value 是否代表 node::BufferUint8Array 对象。

    [out] result: Whether the given napi_value represents a node::Buffer or Uint8Array object.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 检查传入的 Object 是缓冲区还是 Uint8Array。如果调用者需要检查该值是否是 Uint8Array,则应首选 napi_is_typedarray

This API checks if the Object passed in is a buffer or Uint8Array. napi_is_typedarray should be preferred if the caller needs to check if the value is a Uint8Array.

napi_is_date#

napi_status napi_is_date(napi_env env, napi_value value, bool* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要检查的 JavaScript 值。

    [in] value: The JavaScript value to check.

  • [out] result:给定的 napi_value 是否表示 JavaScript Date 对象。

    [out] result: Whether the given napi_value represents a JavaScript Date object.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 检查传入的 Object 是否为日期。

This API checks if the Object passed in is a date.

napi_is_error#

napi_status napi_is_error(napi_env env, napi_value value, bool* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要检查的 JavaScript 值。

    [in] value: The JavaScript value to check.

  • [out] result:给定的 napi_value 是否表示 Error 对象。

    [out] result: Whether the given napi_value represents an Error object.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 检查传入的 Object 是否为 Error

This API checks if the Object passed in is an Error.

napi_is_typedarray#

napi_status napi_is_typedarray(napi_env env, napi_value value, bool* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要检查的 JavaScript 值。

    [in] value: The JavaScript value to check.

  • [out] result:给定的 napi_value 是否代表 TypedArray

    [out] result: Whether the given napi_value represents a TypedArray.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 检查传入的 Object 是否为类型化数组。

This API checks if the Object passed in is a typed array.

napi_is_dataview#

napi_status napi_is_dataview(napi_env env, napi_value value, bool* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要检查的 JavaScript 值。

    [in] value: The JavaScript value to check.

  • [out] result:给定的 napi_value 是否代表 DataView

    [out] result: Whether the given napi_value represents a DataView.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 检查传入的 Object 是否为 DataView

This API checks if the Object passed in is a DataView.

napi_strict_equals#

napi_status napi_strict_equals(napi_env env,
                               napi_value lhs,
                               napi_value rhs,
                               bool* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] lhs:要检查的 JavaScript 值。

    [in] lhs: The JavaScript value to check.

  • [in] rhs:要检查的 JavaScript 值。

    [in] rhs: The JavaScript value to check against.

  • [out] result:两个 napi_value 对象是否相等。

    [out] result: Whether the two napi_value objects are equal.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 表示调用 ECMAScript 语言规范的 第 7.2.14 节 中定义的严格相等算法。

This API represents the invocation of the Strict Equality algorithm as defined in Section 7.2.14 of the ECMAScript Language Specification.

napi_detach_arraybuffer#

napi_status napi_detach_arraybuffer(napi_env env,
                                    napi_value arraybuffer) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] arraybuffer:要分离的 JavaScript ArrayBuffer

    [in] arraybuffer: The JavaScript ArrayBuffer to be detached.

如果 API 成功,则返回 napi_ok。如果传入不可分离的 ArrayBuffer,则返回 napi_detachable_arraybuffer_expected

Returns napi_ok if the API succeeded. If a non-detachable ArrayBuffer is passed in it returns napi_detachable_arraybuffer_expected.

通常,ArrayBuffer 是不可拆卸的,如果它之前已经拆卸过。引擎可能会对 ArrayBuffer 是否可拆卸施加附加条件。例如,V8 要求 ArrayBuffer 是外部的,即用 napi_create_external_arraybuffer 创建的。

Generally, an ArrayBuffer is non-detachable if it has been detached before. The engine may impose additional conditions on whether an ArrayBuffer is detachable. For example, V8 requires that the ArrayBuffer be external, that is, created with napi_create_external_arraybuffer.

此 API 表示调用 ArrayBuffer 分离操作,如 ECMAScript 语言规范的 第 24.1.1.3 节 中所定义。

This API represents the invocation of the ArrayBuffer detach operation as defined in Section 24.1.1.3 of the ECMAScript Language Specification.

napi_is_detached_arraybuffer#

napi_status napi_is_detached_arraybuffer(napi_env env,
                                         napi_value arraybuffer,
                                         bool* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] arraybuffer:要检查的 JavaScript ArrayBuffer

    [in] arraybuffer: The JavaScript ArrayBuffer to be checked.

  • [out] resultarraybuffer 是否分离。

    [out] result: Whether the arraybuffer is detached.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

如果 ArrayBuffer 的内部数据是 null,则认为 ArrayBuffer 已分离。

The ArrayBuffer is considered detached if its internal data is null.

此 API 表示调用 ArrayBuffer IsDetachedBuffer 操作,如 ECMAScript 语言规范的 第 24.1.1.2 节 中所定义。

This API represents the invocation of the ArrayBuffer IsDetachedBuffer operation as defined in Section 24.1.1.2 of the ECMAScript Language Specification.

使用 JavaScript 属性#

Working with JavaScript properties

Node-API 公开了一组 API 来获取和设置 JavaScript 对象的属性。其中一些类型记录在 ECMAScript 语言规范第 7 节 下。

Node-API exposes a set of APIs to get and set properties on JavaScript objects. Some of these types are documented under Section 7 of the ECMAScript Language Specification.

JavaScript 中的属性表示为键和值的元组。从根本上说,Node-API 中的所有属性键都可以用以下形式之一表示:

Properties in JavaScript are represented as a tuple of a key and a value. Fundamentally, all property keys in Node-API can be represented in one of the following forms:

  • 命名:一个简单的 UTF8 编码字符串

    Named: a simple UTF8-encoded string

  • 整数索引:由 uint32_t 表示的索引值

    Integer-Indexed: an index value represented by uint32_t

  • JavaScript 值:这些在 Node-API 中由 napi_value 表示。这可以是代表 stringnumbersymbolnapi_value

    JavaScript value: these are represented in Node-API by napi_value. This can be a napi_value representing a string, number, or symbol.

Node-API 值由类型 napi_value 表示。任何需要 JavaScript 值的 Node-API 调用都采用 napi_value。但是,调用者有责任确保所讨论的 napi_value 是 API 期望的 JavaScript 类型。

Node-API values are represented by the type napi_value. Any Node-API call that requires a JavaScript value takes in a napi_value. However, it's the caller's responsibility to make sure that the napi_value in question is of the JavaScript type expected by the API.

本节中记录的 API 提供了一个简单的接口来获取和设置 napi_value 表示的任意 JavaScript 对象的属性。

The APIs documented in this section provide a simple interface to get and set properties on arbitrary JavaScript objects represented by napi_value.

例如,考虑以下 JavaScript 代码片段:

For instance, consider the following JavaScript code snippet:

const obj = {};
obj.myProp = 123; 

可以通过以下代码段使用 Node-API 值来完成等效操作:

The equivalent can be done using Node-API values with the following snippet:

napi_status status = napi_generic_failure;

// const obj = {}
napi_value obj, value;
status = napi_create_object(env, &obj);
if (status != napi_ok) return status;

// Create a napi_value for 123
status = napi_create_int32(env, 123, &value);
if (status != napi_ok) return status;

// obj.myProp = 123
status = napi_set_named_property(env, obj, "myProp", value);
if (status != napi_ok) return status; 

可以以类似的方式设置索引属性。考虑以下 JavaScript 片段:

Indexed properties can be set in a similar manner. Consider the following JavaScript snippet:

const arr = [];
arr[123] = 'hello'; 

可以通过以下代码段使用 Node-API 值来完成等效操作:

The equivalent can be done using Node-API values with the following snippet:

napi_status status = napi_generic_failure;

// const arr = [];
napi_value arr, value;
status = napi_create_array(env, &arr);
if (status != napi_ok) return status;

// Create a napi_value for 'hello'
status = napi_create_string_utf8(env, "hello", NAPI_AUTO_LENGTH, &value);
if (status != napi_ok) return status;

// arr[123] = 'hello';
status = napi_set_element(env, arr, 123, value);
if (status != napi_ok) return status; 

可以使用本节中描述的 API 检索属性。考虑以下 JavaScript 片段:

Properties can be retrieved using the APIs described in this section. Consider the following JavaScript snippet:

const arr = [];
const value = arr[123]; 

以下是 Node-API 对应物的大致等价物:

The following is the approximate equivalent of the Node-API counterpart:

napi_status status = napi_generic_failure;

// const arr = []
napi_value arr, value;
status = napi_create_array(env, &arr);
if (status != napi_ok) return status;

// const value = arr[123]
status = napi_get_element(env, arr, 123, &value);
if (status != napi_ok) return status; 

最后,出于性能原因,还可以在一个对象上定义多个属性。考虑以下 JavaScript:

Finally, multiple properties can also be defined on an object for performance reasons. Consider the following JavaScript:

const obj = {};
Object.defineProperties(obj, {
  'foo': { value: 123, writable: true, configurable: true, enumerable: true },
  'bar': { value: 456, writable: true, configurable: true, enumerable: true },
}); 

以下是 Node-API 对应物的大致等价物:

The following is the approximate equivalent of the Node-API counterpart:

napi_status status = napi_status_generic_failure;

// const obj = {};
napi_value obj;
status = napi_create_object(env, &obj);
if (status != napi_ok) return status;

// Create napi_values for 123 and 456
napi_value fooValue, barValue;
status = napi_create_int32(env, 123, &fooValue);
if (status != napi_ok) return status;
status = napi_create_int32(env, 456, &barValue);
if (status != napi_ok) return status;

// Set the properties
napi_property_descriptor descriptors[] = {
  { "foo", NULL, NULL, NULL, NULL, fooValue, napi_writable | napi_configurable, NULL },
  { "bar", NULL, NULL, NULL, NULL, barValue, napi_writable | napi_configurable, NULL }
}
status = napi_define_properties(env,
                                obj,
                                sizeof(descriptors) / sizeof(descriptors[0]),
                                descriptors);
if (status != napi_ok) return status; 

结构#

Structures

napi_property_attributes#
typedef enum {
  napi_default = 0,
  napi_writable = 1 << 0,
  napi_enumerable = 1 << 1,
  napi_configurable = 1 << 2,

  // Used with napi_define_class to distinguish static properties
  // from instance properties. Ignored by napi_define_properties.
  napi_static = 1 << 10,

  // Default for class methods.
  napi_default_method = napi_writable | napi_configurable,

  // Default for object properties, like in JS obj[prop].
  napi_default_jsproperty = napi_writable |
                          napi_enumerable |
                          napi_configurable,
} napi_property_attributes; 

napi_property_attributes 是用于控制在 JavaScript 对象上设置的属性行为的标志。除 napi_static 外,它们对应于 ECMAScript 语言规范第 6.1.7.1 节 中列出的属性。它们可以是以下一个或多个位标志:

napi_property_attributes are flags used to control the behavior of properties set on a JavaScript object. Other than napi_static they correspond to the attributes listed in Section 6.1.7.1 of the ECMAScript Language Specification. They can be one or more of the following bitflags:

  • napi_default:没有在属性上设置显式属性。默认情况下,属性是只读的,不可枚举且不可配置。

    napi_default: No explicit attributes are set on the property. By default, a property is read only, not enumerable and not configurable.

  • napi_writable:该属性是可写的。

    napi_writable: The property is writable.

  • napi_enumerable:该属性是可枚举的。

    napi_enumerable: The property is enumerable.

  • napi_configurable:该属性可按照 ECMAScript 语言规范第 6.1.7.1 节 中的定义进行配置。

    napi_configurable: The property is configurable as defined in Section 6.1.7.1 of the ECMAScript Language Specification.

  • napi_static:该属性将被定义为类的静态属性,而不是默认的实例属性。这仅由 napi_define_class 使用。它被 napi_define_properties 忽略。

    napi_static: The property will be defined as a static property on a class as opposed to an instance property, which is the default. This is used only by napi_define_class. It is ignored by napi_define_properties.

  • napi_default_method:就像 JS 类中的方法一样,该属性是可配置和可写的,但不可枚举。

    napi_default_method: Like a method in a JS class, the property is configurable and writeable, but not enumerable.

  • napi_default_jsproperty:就像 JavaScript 中通过赋值设置的属性一样,属性是可写、可枚举和可配置的。

    napi_default_jsproperty: Like a property set via assignment in JavaScript, the property is writable, enumerable, and configurable.

napi_property_descriptor#
typedef struct {
  // One of utf8name or name should be NULL.
  const char* utf8name;
  napi_value name;

  napi_callback method;
  napi_callback getter;
  napi_callback setter;
  napi_value value;

  napi_property_attributes attributes;
  void* data;
} napi_property_descriptor; 
  • utf8name:描述属性键的可选字符串,编码为 UTF8。必须为属性提供 utf8namename 之一。

    utf8name: Optional string describing the key for the property, encoded as UTF8. One of utf8name or name must be provided for the property.

  • name:可选的 napi_value,指向用作属性键的 JavaScript 字符串或符号。必须为属性提供 utf8namename 之一。

    name: Optional napi_value that points to a JavaScript string or symbol to be used as the key for the property. One of utf8name or name must be provided for the property.

  • value:如果属性是数据属性,则通过属性的 get 访问检索到的值。如果传入,则将 gettersettermethoddata 设置为 NULL(因为不会使用这些成员)。

    value: The value that's retrieved by a get access of the property if the property is a data property. If this is passed in, set getter, setter, method and data to NULL (since these members won't be used).

  • getter:执行对属性的获取访问时调用的函数。如果传入,则将 valuemethod 设置为 NULL(因为不会使用这些成员)。当从 JavaScript 代码访问属性时(或者如果使用 Node-API 调用执行对属性的获取),运行时将隐式调用给定函数。napi_callback 提供了更多详细信息。

    getter: A function to call when a get access of the property is performed. If this is passed in, set value and method to NULL (since these members won't be used). The given function is called implicitly by the runtime when the property is accessed from JavaScript code (or if a get on the property is performed using a Node-API call). napi_callback provides more details.

  • setter:执行属性的设置访问时调用的函数。如果传入,则将 valuemethod 设置为 NULL(因为不会使用这些成员)。当从 JavaScript 代码设置属性时(或者如果使用 Node-API 调用执行属性设置),运行时将隐式调用给定函数。napi_callback 提供了更多详细信息。

    setter: A function to call when a set access of the property is performed. If this is passed in, set value and method to NULL (since these members won't be used). The given function is called implicitly by the runtime when the property is set from JavaScript code (or if a set on the property is performed using a Node-API call). napi_callback provides more details.

  • method:设置此项使属性描述符对象的 value 属性成为 method 表示的 JavaScript 函数。如果传入,则将 valuegettersetter 设置为 NULL(因为不会使用这些成员)。napi_callback 提供了更多详细信息。

    method: Set this to make the property descriptor object's value property to be a JavaScript function represented by method. If this is passed in, set value, getter and setter to NULL (since these members won't be used). napi_callback provides more details.

  • attributes:与特定属性关联的属性。参见 napi_property_attributes

    attributes: The attributes associated with the particular property. See napi_property_attributes.

  • data:如果调用此函数,回调数据将传递到 methodgettersetter

    data: The callback data passed into method, getter and setter if this function is invoked.

函数#

Functions

napi_get_property_names#
napi_status napi_get_property_names(napi_env env,
                                    napi_value object,
                                    napi_value* result); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:从中检索属性的对象。

    [in] object: The object from which to retrieve the properties.

  • [out] result:一个 napi_value,表示一个 JavaScript 值数组,这些值表示对象的属性名称。API 可用于使用 napi_get_array_lengthnapi_get_element 迭代 result

    [out] result: A napi_value representing an array of JavaScript values that represent the property names of the object. The API can be used to iterate over result using napi_get_array_length and napi_get_element.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 以字符串数组的形式返回 object 的可枚举属性的名称。key 为符号的 object 的属性将不会被包含在内。

This API returns the names of the enumerable properties of object as an array of strings. The properties of object whose key is a symbol will not be included.

napi_get_all_property_names#
napi_get_all_property_names(napi_env env,
                            napi_value object,
                            napi_key_collection_mode key_mode,
                            napi_key_filter key_filter,
                            napi_key_conversion key_conversion,
                            napi_value* result); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:从中检索属性的对象。

    [in] object: The object from which to retrieve the properties.

  • [in] key_mode:是否也检索原型属性。

    [in] key_mode: Whether to retrieve prototype properties as well.

  • [in] key_filter:要检索哪些属性(可枚举/可读/可写)。

    [in] key_filter: Which properties to retrieve (enumerable/readable/writable).

  • [in] key_conversion:是否将编号的属性键转换为字符串。

    [in] key_conversion: Whether to convert numbered property keys to strings.

  • [out] result:一个 napi_value,表示一个 JavaScript 值数组,这些值表示对象的属性名称。napi_get_array_lengthnapi_get_element 可用于迭代 result

    [out] result: A napi_value representing an array of JavaScript values that represent the property names of the object. napi_get_array_length and napi_get_element can be used to iterate over result.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 返回一个数组,其中包含此对象的可用属性的名称。

This API returns an array containing the names of the available properties of this object.

napi_set_property#
napi_status napi_set_property(napi_env env,
                              napi_value object,
                              napi_value key,
                              napi_value value); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:要对其设置属性的对象。

    [in] object: The object on which to set the property.

  • [in] key:要设置的属性的名称。

    [in] key: The name of the property to set.

  • [in] value:属性值。

    [in] value: The property value.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 在传入的 Object 上设置了一个属性。

This API set a property on the Object passed in.

napi_get_property#
napi_status napi_get_property(napi_env env,
                              napi_value object,
                              napi_value key,
                              napi_value* result); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:从中检索属性的对象。

    [in] object: The object from which to retrieve the property.

  • [in] key:要检索的属性的名称。

    [in] key: The name of the property to retrieve.

  • [out] result:属性的值。

    [out] result: The value of the property.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 从传入的 Object 中获取请求的属性。

This API gets the requested property from the Object passed in.

napi_has_property#
napi_status napi_has_property(napi_env env,
                              napi_value object,
                              napi_value key,
                              bool* result); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:要查询的对象。

    [in] object: The object to query.

  • [in] key:要检查其存在的属性的名称。

    [in] key: The name of the property whose existence to check.

  • [out] result:该属性是否存在于对象上。

    [out] result: Whether the property exists on the object or not.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 检查传入的 Object 是否具有命名属性。

This API checks if the Object passed in has the named property.

napi_delete_property#
napi_status napi_delete_property(napi_env env,
                                 napi_value object,
                                 napi_value key,
                                 bool* result); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:要查询的对象。

    [in] object: The object to query.

  • [in] key:要删除的属性的名称。

    [in] key: The name of the property to delete.

  • [out] result:属性删除是否成功。result 可以选择性地通过传递 NULL 来忽略。

    [out] result: Whether the property deletion succeeded or not. result can optionally be ignored by passing NULL.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 尝试从 object 中删除 key 自己的属性。

This API attempts to delete the key own property from object.

napi_has_own_property#
napi_status napi_has_own_property(napi_env env,
                                  napi_value object,
                                  napi_value key,
                                  bool* result); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:要查询的对象。

    [in] object: The object to query.

  • [in] key:要检查其存在的自有属性的名称。

    [in] key: The name of the own property whose existence to check.

  • [out] result:对象上是否存在自己的属性。

    [out] result: Whether the own property exists on the object or not.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 检查传入的 Object 是否具有命名的自己的属性。key 必须是 stringsymbol,否则将抛出错误。Node-API 不会执行任何数据类型之间的转换。

This API checks if the Object passed in has the named own property. key must be a string or a symbol, or an error will be thrown. Node-API will not perform any conversion between data types.

napi_set_named_property#
napi_status napi_set_named_property(napi_env env,
                                    napi_value object,
                                    const char* utf8Name,
                                    napi_value value); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:要对其设置属性的对象。

    [in] object: The object on which to set the property.

  • [in] utf8Name:要设置的属性的名称。

    [in] utf8Name: The name of the property to set.

  • [in] value:属性值。

    [in] value: The property value.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此方法等效于使用从作为 utf8Name 传入的字符串创建的 napi_value 调用 napi_set_property

This method is equivalent to calling napi_set_property with a napi_value created from the string passed in as utf8Name.

napi_get_named_property#
napi_status napi_get_named_property(napi_env env,
                                    napi_value object,
                                    const char* utf8Name,
                                    napi_value* result); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:从中检索属性的对象。

    [in] object: The object from which to retrieve the property.

  • [in] utf8Name:要获取的属性的名称。

    [in] utf8Name: The name of the property to get.

  • [out] result:属性的值。

    [out] result: The value of the property.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此方法等效于使用从作为 utf8Name 传入的字符串创建的 napi_value 调用 napi_get_property

This method is equivalent to calling napi_get_property with a napi_value created from the string passed in as utf8Name.

napi_has_named_property#
napi_status napi_has_named_property(napi_env env,
                                    napi_value object,
                                    const char* utf8Name,
                                    bool* result); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:要查询的对象。

    [in] object: The object to query.

  • [in] utf8Name:要检查其存在的属性的名称。

    [in] utf8Name: The name of the property whose existence to check.

  • [out] result:该属性是否存在于对象上。

    [out] result: Whether the property exists on the object or not.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此方法等效于使用从作为 utf8Name 传入的字符串创建的 napi_value 调用 napi_has_property

This method is equivalent to calling napi_has_property with a napi_value created from the string passed in as utf8Name.

napi_set_element#
napi_status napi_set_element(napi_env env,
                             napi_value object,
                             uint32_t index,
                             napi_value value); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:从中设置属性的对象。

    [in] object: The object from which to set the properties.

  • [in] index:要设置的属性的索引。

    [in] index: The index of the property to set.

  • [in] value:属性值。

    [in] value: The property value.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

该 API 在传入的 Object 上设置一个元素。

This API sets an element on the Object passed in.

napi_get_element#
napi_status napi_get_element(napi_env env,
                             napi_value object,
                             uint32_t index,
                             napi_value* result); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:从中检索属性的对象。

    [in] object: The object from which to retrieve the property.

  • [in] index:要获取的属性的索引。

    [in] index: The index of the property to get.

  • [out] result:属性的值。

    [out] result: The value of the property.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 获取请求索引处的元素。

This API gets the element at the requested index.

napi_has_element#
napi_status napi_has_element(napi_env env,
                             napi_value object,
                             uint32_t index,
                             bool* result); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:要查询的对象。

    [in] object: The object to query.

  • [in] index:要检查其存在的属性的索引。

    [in] index: The index of the property whose existence to check.

  • [out] result:该属性是否存在于对象上。

    [out] result: Whether the property exists on the object or not.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

如果传入的 Object 在请求的索引处有一个元素,则此 API 返回。

This API returns if the Object passed in has an element at the requested index.

napi_delete_element#
napi_status napi_delete_element(napi_env env,
                                napi_value object,
                                uint32_t index,
                                bool* result); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:要查询的对象。

    [in] object: The object to query.

  • [in] index:要删除的属性的索引。

    [in] index: The index of the property to delete.

  • [out] result:删除元素是否成功。result 可以选择性地通过传递 NULL 来忽略。

    [out] result: Whether the element deletion succeeded or not. result can optionally be ignored by passing NULL.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 尝试从 object 中删除指定的 index

This API attempts to delete the specified index from object.

napi_define_properties#
napi_status napi_define_properties(napi_env env,
                                   napi_value object,
                                   size_t property_count,
                                   const napi_property_descriptor* properties); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:从中检索属性的对象。

    [in] object: The object from which to retrieve the properties.

  • [in] property_countproperties 数组中的元素数。

    [in] property_count: The number of elements in the properties array.

  • [in] properties:属性描述符数组。

    [in] properties: The array of property descriptors.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此方法允许在给定对象上高效定义多个属性。属性是使用属性描述符定义的(参见 napi_property_descriptor)。给定一组此类属性描述符,此 API 将一次设置一个对象的属性,如 DefineOwnProperty() 所定义(在 ECMA-262 规范的 第 9.1.6 节 中描述)。

This method allows the efficient definition of multiple properties on a given object. The properties are defined using property descriptors (see napi_property_descriptor). Given an array of such property descriptors, this API will set the properties on the object one at a time, as defined by DefineOwnProperty() (described in Section 9.1.6 of the ECMA-262 specification).

napi_object_freeze#
napi_status napi_object_freeze(napi_env env,
                               napi_value object); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:要冻结的对象。

    [in] object: The object to freeze.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此方法冻结给定的对象。这可以防止向其添加新属性,删除现有属性,防止更改现有属性的可枚举性、可配置性或可写性,并防止更改现有属性的值。它还可以防止对象的原型被更改。这在 ECMA-262 规范的 第 19.1.2.6 节 中进行了描述。

This method freezes a given object. This prevents new properties from being added to it, existing properties from being removed, prevents changing the enumerability, configurability, or writability of existing properties, and prevents the values of existing properties from being changed. It also prevents the object's prototype from being changed. This is described in Section 19.1.2.6 of the ECMA-262 specification.

napi_object_seal#
napi_status napi_object_seal(napi_env env,
                             napi_value object); 
  • [in] env:调用 Node-API 调用的环境。

    [in] env: The environment that the Node-API call is invoked under.

  • [in] object:要封印的对象。

    [in] object: The object to seal.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此方法密封给定的对象。这可以防止向其添加新属性,以及将所有现有属性标记为不可配置。这在 ECMA-262 规范的 第 19.1.2.20 节 中进行了描述。

This method seals a given object. This prevents new properties from being added to it, as well as marking all existing properties as non-configurable. This is described in Section 19.1.2.20 of the ECMA-262 specification.

使用 JavaScript 函数#

Working with JavaScript functions

Node-API 提供了一组 API,允许 JavaScript 代码回调原生代码。支持回调原生代码的 Node-API 接受由 napi_callback 类型表示的回调函数。当 JavaScript VM 回调原生代码时,将调用提供的 napi_callback 函数。本节中记录的 API 允许回调函数执行以下操作:

Node-API provides a set of APIs that allow JavaScript code to call back into native code. Node-APIs that support calling back into native code take in a callback functions represented by the napi_callback type. When the JavaScript VM calls back to native code, the napi_callback function provided is invoked. The APIs documented in this section allow the callback function to do the following:

  • 获取有关调用回调的上下文的信息。

    Get information about the context in which the callback was invoked.

  • 获取传递给回调的参数。

    Get the arguments passed into the callback.

  • 从回调中返回 napi_value

    Return a napi_value back from the callback.

此外,Node-API 提供了一组函数,允许从原生代码调用 JavaScript 函数。可以像常规 JavaScript 函数调用一样调用函数,也可以作为构造函数调用。

Additionally, Node-API provides a set of functions which allow calling JavaScript functions from native code. One can either call a function like a regular JavaScript function call, or as a constructor function.

通过 napi_property_descriptor 项的 data 字段传递给此 API 的任何非 NULL 数据都可以与 object 相关联,并在 object 通过将 object 和数据传递给 napi_add_finalizer 进行垃圾回收时释放。

Any non-NULL data which is passed to this API via the data field of the napi_property_descriptor items can be associated with object and freed whenever object is garbage-collected by passing both object and the data to napi_add_finalizer.

napi_call_function#

NAPI_EXTERN napi_status napi_call_function(napi_env env,
                                           napi_value recv,
                                           napi_value func,
                                           size_t argc,
                                           const napi_value* argv,
                                           napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] recv:传递给被调用函数的 this 值。

    [in] recv: The this value passed to the called function.

  • [in] funcnapi_value 表示要调用的 JavaScript 函数。

    [in] func: napi_value representing the JavaScript function to be invoked.

  • [in] argcargv 数组中的元素数。

    [in] argc: The count of elements in the argv array.

  • [in] argvnapi_values 的数组,表示作为参数传递给函数的 JavaScript 值。

    [in] argv: Array of napi_values representing JavaScript values passed in as arguments to the function.

  • [out] resultnapi_value 表示返回的 JavaScript 对象。

    [out] result: napi_value representing the JavaScript object returned.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此方法允许从原生附加组件调用 JavaScript 函数对象。这是从加载项的原生代码回调到 JavaScript 的主要机制。有关在异步操作后调用 JavaScript 的特殊情况,请参阅 napi_make_callback

This method allows a JavaScript function object to be called from a native add-on. This is the primary mechanism of calling back from the add-on's native code into JavaScript. For the special case of calling into JavaScript after an async operation, see napi_make_callback.

示例用例可能如下所示。考虑以下 JavaScript 片段:

A sample use case might look as follows. Consider the following JavaScript snippet:

function AddTwo(num) {
  return num + 2;
}
global.AddTwo = AddTwo; 

然后,可以使用以下代码从原生附加组件调用上述函数:

Then, the above function can be invoked from a native add-on using the following code:

// Get the function named "AddTwo" on the global object
napi_value global, add_two, arg;
napi_status status = napi_get_global(env, &global);
if (status != napi_ok) return;

status = napi_get_named_property(env, global, "AddTwo", &add_two);
if (status != napi_ok) return;

// const arg = 1337
status = napi_create_int32(env, 1337, &arg);
if (status != napi_ok) return;

napi_value* argv = &arg;
size_t argc = 1;

// AddTwo(arg);
napi_value return_val;
status = napi_call_function(env, global, add_two, argc, argv, &return_val);
if (status != napi_ok) return;

// Convert the result back to a native type
int32_t result;
status = napi_get_value_int32(env, return_val, &result);
if (status != napi_ok) return; 

napi_create_function#

napi_status napi_create_function(napi_env env,
                                 const char* utf8name,
                                 size_t length,
                                 napi_callback cb,
                                 void* data,
                                 napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] utf8Name:编码为 UTF8 的函数的可选名称。这在 JavaScript 中是可见的,作为新函数对象的 name 属性。

    [in] utf8Name: Optional name of the function encoded as UTF8. This is visible within JavaScript as the new function object's name property.

  • [in] lengthutf8name 的长度(以字节为单位)或 NAPI_AUTO_LENGTH(如果以 null 结尾)。

    [in] length: The length of the utf8name in bytes, or NAPI_AUTO_LENGTH if it is null-terminated.

  • [in] cb:调用此函数对象时应调用的原生函数。napi_callback 提供了更多详细信息。

    [in] cb: The native function which should be called when this function object is invoked. napi_callback provides more details.

  • [in] data:用户提供的数据上下文。这将在稍后调用时传回函数。

    [in] data: User-provided data context. This will be passed back into the function when invoked later.

  • [out] resultnapi_value 表示新创建函数的 JavaScript 函数对象。

    [out] result: napi_value representing the JavaScript function object for the newly created function.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 允许插件作者以原生代码创建函数对象。这是允许从 JavaScript 调用加载项的原生代码的主要机制。

This API allows an add-on author to create a function object in native code. This is the primary mechanism to allow calling into the add-on's native code from JavaScript.

在此调用之后,新创建的函数不会自动从脚本中可见。相反,必须在 JavaScript 可见的任何对象上显式设置属性,以便可以从脚本访问该函数。

The newly created function is not automatically visible from script after this call. Instead, a property must be explicitly set on any object that is visible to JavaScript, in order for the function to be accessible from script.

为了将函数公开为附加模块导出的一部分,请在导出对象上设置新创建的函数。示例模块可能如下所示:

In order to expose a function as part of the add-on's module exports, set the newly created function on the exports object. A sample module might look as follows:

napi_value SayHello(napi_env env, napi_callback_info info) {
  printf("Hello\n");
  return NULL;
}

napi_value Init(napi_env env, napi_value exports) {
  napi_status status;

  napi_value fn;
  status = napi_create_function(env, NULL, 0, SayHello, NULL, &fn);
  if (status != napi_ok) return NULL;

  status = napi_set_named_property(env, exports, "sayHello", fn);
  if (status != napi_ok) return NULL;

  return exports;
}

NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) 

鉴于以上代码,可以从 JavaScript 中使用附加组件,如下所示:

Given the above code, the add-on can be used from JavaScript as follows:

const myaddon = require('./addon');
myaddon.sayHello(); 

传递给 require() 的字符串是 binding.gyp 中负责创建 .node 文件的目标的名称。

The string passed to require() is the name of the target in binding.gyp responsible for creating the .node file.

通过 data 参数传递给此 API 的任何非 NULL 数据都可以与生成的 JavaScript 函数(在 result 参数中返回)相关联,并在通过传递 JavaScript 函数和数据对函数进行垃圾回收时释放 到 napi_add_finalizer

Any non-NULL data which is passed to this API via the data parameter can be associated with the resulting JavaScript function (which is returned in the result parameter) and freed whenever the function is garbage-collected by passing both the JavaScript function and the data to napi_add_finalizer.

JavaScript Function 在 ECMAScript 语言规范的 第 19.2 节 中描述。

JavaScript Functions are described in Section 19.2 of the ECMAScript Language Specification.

napi_get_cb_info#

napi_status napi_get_cb_info(napi_env env,
                             napi_callback_info cbinfo,
                             size_t* argc,
                             napi_value* argv,
                             napi_value* thisArg,
                             void** data) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] cbinfo:传递给回调函数的回调信息。

    [in] cbinfo: The callback info passed into the callback function.

  • [in-out] argc:指定所提供的 argv 数组的长度并接收参数的实际计数。argc 可以选择性地通过传递 NULL 来忽略。

    [in-out] argc: Specifies the length of the provided argv array and receives the actual count of arguments. argc can optionally be ignored by passing NULL.

  • [out] argv:参数将被复制到的 napi_value 的 C 数组。如果参数数量多于提供的数量,则只复制请求数量的参数。如果提供的参数比声明的少,则 argv 的其余部分将填充代表 undefinednapi_value 值。argv 可以选择性地通过传递 NULL 来忽略。

    [out] argv: C array of napi_values to which the arguments will be copied. If there are more arguments than the provided count, only the requested number of arguments are copied. If there are fewer arguments provided than claimed, the rest of argv is filled with napi_value values that represent undefined. argv can optionally be ignored by passing NULL.

  • [out] thisArg:接收调用的 JavaScript this 参数。thisArg 可以选择性地通过传递 NULL 来忽略。

    [out] thisArg: Receives the JavaScript this argument for the call. thisArg can optionally be ignored by passing NULL.

  • [out] data:接收回调的数据指针。data 可以选择性地通过传递 NULL 来忽略。

    [out] data: Receives the data pointer for the callback. data can optionally be ignored by passing NULL.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此方法在回调函数中用于检索有关调用的详细信息,例如来自给定回调信息的参数和 this 指针。

This method is used within a callback function to retrieve details about the call like the arguments and the this pointer from a given callback info.

napi_get_new_target#

napi_status napi_get_new_target(napi_env env,
                                napi_callback_info cbinfo,
                                napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] cbinfo:传递给回调函数的回调信息。

    [in] cbinfo: The callback info passed into the callback function.

  • [out] result:构造函数调用的 new.target

    [out] result: The new.target of the constructor call.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 返回构造函数调用的 new.target。如果当前回调不是构造函数调用,则结果为 NULL

This API returns the new.target of the constructor call. If the current callback is not a constructor call, the result is NULL.

napi_new_instance#

napi_status napi_new_instance(napi_env env,
                              napi_value cons,
                              size_t argc,
                              napi_value* argv,
                              napi_value* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] consnapi_value 表示要作为构造函数调用的 JavaScript 函数。

    [in] cons: napi_value representing the JavaScript function to be invoked as a constructor.

  • [in] argcargv 数组中的元素数。

    [in] argc: The count of elements in the argv array.

  • [in] argv:JavaScript 值数组 napi_value 表示构造函数的参数。如果 argc 为零,则可以通过传入 NULL 来省略此参数。

    [in] argv: Array of JavaScript values as napi_value representing the arguments to the constructor. If argc is zero this parameter may be omitted by passing in NULL.

  • [out] resultnapi_value 表示返回的 JavaScript 对象,在本例中是构造的对象。

    [out] result: napi_value representing the JavaScript object returned, which in this case is the constructed object.

此方法用于使用给定的 napi_value 表示对象的构造函数来实例化新的 JavaScript 值。例如,考虑以下片段:

This method is used to instantiate a new JavaScript value using a given napi_value that represents the constructor for the object. For example, consider the following snippet:

function MyObject(param) {
  this.param = param;
}

const arg = 'hello';
const value = new MyObject(arg); 

可以使用以下代码片段在 Node-API 中近似计算以下内容:

The following can be approximated in Node-API using the following snippet:

// Get the constructor function MyObject
napi_value global, constructor, arg, value;
napi_status status = napi_get_global(env, &global);
if (status != napi_ok) return;

status = napi_get_named_property(env, global, "MyObject", &constructor);
if (status != napi_ok) return;

// const arg = "hello"
status = napi_create_string_utf8(env, "hello", NAPI_AUTO_LENGTH, &arg);
if (status != napi_ok) return;

napi_value* argv = &arg;
size_t argc = 1;

// const value = new MyObject(arg)
status = napi_new_instance(env, constructor, argc, argv, &value); 

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

对象封装#

Object wrap

Node-API 为 "wrap" C++ 类和实例提供了一种方法,以便可以从 JavaScript 调用类构造函数和方法。

Node-API offers a way to "wrap" C++ classes and instances so that the class constructor and methods can be called from JavaScript.

  1. napi_define_class API 定义了一个 JavaScript 类,其中包含与 C++ 类对应的构造函数、静态属性和方法以及实例属性和方法。

    The napi_define_class API defines a JavaScript class with constructor, static properties and methods, and instance properties and methods that correspond to the C++ class.

  2. 当 JavaScript 代码调用构造函数时,构造函数回调使用 napi_wrap 将新的 C++ 实例封装在 JavaScript 对象中,然后返回封装对象。

    When JavaScript code invokes the constructor, the constructor callback uses napi_wrap to wrap a new C++ instance in a JavaScript object, then returns the wrapper object.

  3. 当 JavaScript 代码调用类上的方法或属性访问器时,将调用相应的 napi_callback C++ 函数。对于实例回调,napi_unwrap 获取作为调用目标的 C++ 实例。

    When JavaScript code invokes a method or property accessor on the class, the corresponding napi_callback C++ function is invoked. For an instance callback, napi_unwrap obtains the C++ instance that is the target of the call.

对于封装对象,可能很难区分在类原型上调用的函数和在类实例上调用的函数。用于解决此问题的一种常见模式是保存对类构造函数的持久引用,以供以后进行 instanceof 检查。

For wrapped objects it may be difficult to distinguish between a function called on a class prototype and a function called on an instance of a class. A common pattern used to address this problem is to save a persistent reference to the class constructor for later instanceof checks.

napi_value MyClass_constructor = NULL;
status = napi_get_reference_value(env, MyClass::es_constructor, &MyClass_constructor);
assert(napi_ok == status);
bool is_instance = false;
status = napi_instanceof(env, es_this, MyClass_constructor, &is_instance);
assert(napi_ok == status);
if (is_instance) {
  // napi_unwrap() ...
} else {
  // otherwise...
} 

一旦不再需要引用,就必须将其释放。

The reference must be freed once it is no longer needed.

在某些情况下,napi_instanceof() 不足以确保 JavaScript 对象是某种原生类型的封装器。尤其是当封装的 JavaScript 对象通过静态方法而不是作为原型方法的 this 值传递回插件时。在这种情况下,它们有可能被错误地解包。

There are occasions where napi_instanceof() is insufficient for ensuring that a JavaScript object is a wrapper for a certain native type. This is the case especially when wrapped JavaScript objects are passed back into the addon via static methods rather than as the this value of prototype methods. In such cases there is a chance that they may be unwrapped incorrectly.

const myAddon = require('./build/Release/my_addon.node');

// `openDatabase()` returns a JavaScript object that wraps a native database
// handle.
const dbHandle = myAddon.openDatabase();

// `query()` returns a JavaScript object that wraps a native query handle.
const queryHandle = myAddon.query(dbHandle, 'Gimme ALL the things!');

// There is an accidental error in the line below. The first parameter to
// `myAddon.queryHasRecords()` should be the database handle (`dbHandle`), not
// the query handle (`query`), so the correct condition for the while-loop
// should be
//
// myAddon.queryHasRecords(dbHandle, queryHandle)
//
while (myAddon.queryHasRecords(queryHandle, dbHandle)) {
  // retrieve records
} 

在上面的示例中,myAddon.queryHasRecords() 是一个接受两个参数的方法。第一个是数据库句柄,第二个是查询句柄。在内部,它解开第一个参数并将结果指针转换为原生数据库句柄。然后它解包第二个参数并将结果指针转换为查询句柄。如果参数以错误的顺序传递,转换将起作用,但是,底层数据库操作很可能会失败,甚至会导致无效的内存访问。

In the above example myAddon.queryHasRecords() is a method that accepts two arguments. The first is a database handle and the second is a query handle. Internally, it unwraps the first argument and casts the resulting pointer to a native database handle. It then unwraps the second argument and casts the resulting pointer to a query handle. If the arguments are passed in the wrong order, the casts will work, however, there is a good chance that the underlying database operation will fail, or will even cause an invalid memory access.

为了确保从第一个参数中检索到的指针确实是指向数据库句柄的指针,并且类似地,从第二个参数中检索到的指针确实是指向查询句柄的指针,queryHasRecords() 的实现必须执行类型验证。在 napi_ref 中保留实例化数据库句柄的 JavaScript 类构造函数和实例化查询句柄的构造函数会有所帮助,因为 napi_instanceof() 然后可用于确保传递到 queryHashRecords() 的实例确实是正确的类型。

To ensure that the pointer retrieved from the first argument is indeed a pointer to a database handle and, similarly, that the pointer retrieved from the second argument is indeed a pointer to a query handle, the implementation of queryHasRecords() has to perform a type validation. Retaining the JavaScript class constructor from which the database handle was instantiated and the constructor from which the query handle was instantiated in napi_refs can help, because napi_instanceof() can then be used to ensure that the instances passed into queryHashRecords() are indeed of the correct type.

不幸的是,napi_instanceof() 不能防止原型操作。例如,数据库句柄实例的原型可以设置为查询句柄实例的构造函数的原型。在这种情况下,数据库句柄实例可以作为查询句柄实例出现,它将通过查询句柄实例的 napi_instanceof() 测试,同时仍包含指向数据库句柄的指针。

Unfortunately, napi_instanceof() does not protect against prototype manipulation. For example, the prototype of the database handle instance can be set to the prototype of the constructor for query handle instances. In this case, the database handle instance can appear as a query handle instance, and it will pass the napi_instanceof() test for a query handle instance, while still containing a pointer to a database handle.

为此,Node-API 提供了类型标记功能。

To this end, Node-API provides type-tagging capabilities.

类型标签是插件独有的 128 位整数。Node-API 提供了用于存储类型标签的 napi_type_tag 结构。当这样的值与存储在 napi_valuenapi_type_tag_object() 中的 JavaScript 对象或 外部的 一起传递时,JavaScript 对象将是带有类型标记的 "marked"。"mark" 在 JavaScript 端是不可见的。当 JavaScript 对象到达原生绑定时,可以使用 napi_check_object_type_tag() 和原始类型标签来确定 JavaScript 对象之前是否是带有类型标签的 "marked"。这创建了比 napi_instanceof() 可以提供的保真度更高的类型检查功能,因为这种类型标记在原型操作和插件卸载/重新加载后仍然存在。

A type tag is a 128-bit integer unique to the addon. Node-API provides the napi_type_tag structure for storing a type tag. When such a value is passed along with a JavaScript object or external stored in a napi_value to napi_type_tag_object(), the JavaScript object will be "marked" with the type tag. The "mark" is invisible on the JavaScript side. When a JavaScript object arrives into a native binding, napi_check_object_type_tag() can be used along with the original type tag to determine whether the JavaScript object was previously "marked" with the type tag. This creates a type-checking capability of a higher fidelity than napi_instanceof() can provide, because such type- tagging survives prototype manipulation and addon unloading/reloading.

继续上面的例子,下面的框架插件实现说明了 napi_type_tag_object()napi_check_object_type_tag() 的使用。

Continuing the above example, the following skeleton addon implementation illustrates the use of napi_type_tag_object() and napi_check_object_type_tag().

// This value is the type tag for a database handle. The command
//
//   uuidgen | sed -r -e 's/-//g' -e 's/(.{16})(.*)/0x\1, 0x\2/'
//
// can be used to obtain the two values with which to initialize the structure.
static const napi_type_tag DatabaseHandleTypeTag = {
  0x1edf75a38336451d, 0xa5ed9ce2e4c00c38
};

// This value is the type tag for a query handle.
static const napi_type_tag QueryHandleTypeTag = {
  0x9c73317f9fad44a3, 0x93c3920bf3b0ad6a
};

static napi_value
openDatabase(napi_env env, napi_callback_info info) {
  napi_status status;
  napi_value result;

  // Perform the underlying action which results in a database handle.
  DatabaseHandle* dbHandle = open_database();

  // Create a new, empty JS object.
  status = napi_create_object(env, &result);
  if (status != napi_ok) return NULL;

  // Tag the object to indicate that it holds a pointer to a `DatabaseHandle`.
  status = napi_type_tag_object(env, result, &DatabaseHandleTypeTag);
  if (status != napi_ok) return NULL;

  // Store the pointer to the `DatabaseHandle` structure inside the JS object.
  status = napi_wrap(env, result, dbHandle, NULL, NULL, NULL);
  if (status != napi_ok) return NULL;

  return result;
}

// Later when we receive a JavaScript object purporting to be a database handle
// we can use `napi_check_object_type_tag()` to ensure that it is indeed such a
// handle.

static napi_value
query(napi_env env, napi_callback_info info) {
  napi_status status;
  size_t argc = 2;
  napi_value argv[2];
  bool is_db_handle;

  status = napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
  if (status != napi_ok) return NULL;

  // Check that the object passed as the first parameter has the previously
  // applied tag.
  status = napi_check_object_type_tag(env,
                                      argv[0],
                                      &DatabaseHandleTypeTag,
                                      &is_db_handle);
  if (status != napi_ok) return NULL;

  // Throw a `TypeError` if it doesn't.
  if (!is_db_handle) {
    // Throw a TypeError.
    return NULL;
  }
} 

napi_define_class#

napi_status napi_define_class(napi_env env,
                              const char* utf8name,
                              size_t length,
                              napi_callback constructor,
                              void* data,
                              size_t property_count,
                              const napi_property_descriptor* properties,
                              napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] utf8name:JavaScript 构造函数的名称。为清楚起见,建议在封装 C++ 类时使用 C++ 类名。

    [in] utf8name: Name of the JavaScript constructor function. For clarity, it is recommended to use the C++ class name when wrapping a C++ class.

  • [in] lengthutf8name 的长度(以字节为单位)或 NAPI_AUTO_LENGTH(如果以 null 结尾)。

    [in] length: The length of the utf8name in bytes, or NAPI_AUTO_LENGTH if it is null-terminated.

  • [in] constructor:处理类的构造实例的回调函数。封装 C++ 类时,此方法必须是具有 napi_callback 签名的静态成员。不能使用 C++ 类构造函数。napi_callback 提供了更多详细信息。

    [in] constructor: Callback function that handles constructing instances of the class. When wrapping a C++ class, this method must be a static member with the napi_callback signature. A C++ class constructor cannot be used. napi_callback provides more details.

  • [in] data:作为回调信息的 data 属性传递给构造函数回调的可选数据。

    [in] data: Optional data to be passed to the constructor callback as the data property of the callback info.

  • [in] property_countproperties 数组参数中的项数。

    [in] property_count: Number of items in the properties array argument.

  • [in] properties:描述类静态和实例数据属性、访问器和方法的属性描述符数组 请参见 napi_property_descriptor

    [in] properties: Array of property descriptors describing static and instance data properties, accessors, and methods on the class See napi_property_descriptor.

  • [out] result:表示类的构造函数的 napi_value

    [out] result: A napi_value representing the constructor function for the class.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

定义一个 JavaScript 类,包括:

Defines a JavaScript class, including:

  • 具有类名的 JavaScript 构造函数。当封装相应的 C++ 类时,通过 constructor 传递的回调可用于实例化一个新的 C++ 类实例,然后将其放置在使用 napi_wrap 构造的 JavaScript 对象实例中。

    A JavaScript constructor function that has the class name. When wrapping a corresponding C++ class, the callback passed via constructor can be used to instantiate a new C++ class instance, which can then be placed inside the JavaScript object instance being constructed using napi_wrap.

  • 构造函数上的属性,其实现可以调用 C++ 类的相应静态数据属性、访问器和方法(由具有 napi_static 属性的属性描述符定义)。

    Properties on the constructor function whose implementation can call corresponding static data properties, accessors, and methods of the C++ class (defined by property descriptors with the napi_static attribute).

  • 构造函数的 prototype 对象的属性。封装 C++ 类时,在检索放置在 JavaScript 对象实例中的 C++ 类实例后,可以从属性描述符中给定的静态函数调用 C++ 类的非静态数据属性、访问器和方法,而无需使用 napi_static 属性 napi_unwrap

    Properties on the constructor function's prototype object. When wrapping a C++ class, non-static data properties, accessors, and methods of the C++ class can be called from the static functions given in the property descriptors without the napi_static attribute after retrieving the C++ class instance placed inside the JavaScript object instance by using napi_unwrap.

封装 C++ 类时,通过 constructor 传递的 C++ 构造函数回调应该是调用实际类构造函数的类的静态方法,然后将新的 C++ 实例封装在 JavaScript 对象中,并返回封装器对象。详见 napi_wrap

When wrapping a C++ class, the C++ constructor callback passed via constructor should be a static method on the class that calls the actual class constructor, then wraps the new C++ instance in a JavaScript object, and returns the wrapper object. See napi_wrap for details.

napi_define_class 返回的 JavaScript 构造函数通常被保存并在以后用于从原生代码构造类的新实例,和/或检查提供的值是否是类的实例。在这种情况下,为了防止函数值被垃圾收集,可以使用 napi_create_reference 创建对其的强持久引用,确保引用计数保持 >= 1。

The JavaScript constructor function returned from napi_define_class is often saved and used later to construct new instances of the class from native code, and/or to check whether provided values are instances of the class. In that case, to prevent the function value from being garbage-collected, a strong persistent reference to it can be created using napi_create_reference, ensuring that the reference count is kept >= 1.

通过 data 参数或 napi_property_descriptor 数组项的 data 字段传递给此 API 的任何非 NULL 数据都可以与生成的 JavaScript 构造函数(在 result 参数中返回)相关联,并在类为垃圾时释放 - 通过将 JavaScript 函数和数据传递给 napi_add_finalizer 来收集。

Any non-NULL data which is passed to this API via the data parameter or via the data field of the napi_property_descriptor array items can be associated with the resulting JavaScript constructor (which is returned in the result parameter) and freed whenever the class is garbage-collected by passing both the JavaScript function and the data to napi_add_finalizer.

napi_wrap#

napi_status napi_wrap(napi_env env,
                      napi_value js_object,
                      void* native_object,
                      napi_finalize finalize_cb,
                      void* finalize_hint,
                      napi_ref* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] js_object:将成为原生对象封装器的 JavaScript 对象。

    [in] js_object: The JavaScript object that will be the wrapper for the native object.

  • [in] native_object:将封装在 JavaScript 对象中的原生实例。

    [in] native_object: The native instance that will be wrapped in the JavaScript object.

  • [in] finalize_cb:可选的原生回调,可用于在 JavaScript 对象被垃圾回收时释放原生实例。napi_finalize 提供了更多详细信息。

    [in] finalize_cb: Optional native callback that can be used to free the native instance when the JavaScript object has been garbage-collected. napi_finalize provides more details.

  • [in] finalize_hint:传递给完成回调的可选上下文提示。

    [in] finalize_hint: Optional contextual hint that is passed to the finalize callback.

  • [out] result:对封装对象的可选引用。

    [out] result: Optional reference to the wrapped object.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

在 JavaScript 对象中封装原生实例。稍后可以使用 napi_unwrap() 检索原生实例。

Wraps a native instance in a JavaScript object. The native instance can be retrieved later using napi_unwrap().

当 JavaScript 代码调用使用 napi_define_class() 定义的类的构造函数时,将调用构造函数的 napi_callback。构造原生类的实例后,回调必须调用 napi_wrap() 以将新构造的实例封装在已创建的 JavaScript 对象中,该对象是构造函数回调的 this 参数。(this 对象是从构造函数的 prototype 创建的,因此它已经具有所有实例属性和方法的定义。)

When JavaScript code invokes a constructor for a class that was defined using napi_define_class(), the napi_callback for the constructor is invoked. After constructing an instance of the native class, the callback must then call napi_wrap() to wrap the newly constructed instance in the already-created JavaScript object that is the this argument to the constructor callback. (That this object was created from the constructor function's prototype, so it already has definitions of all the instance properties and methods.)

通常在封装类实例时,应该提供一个终结回调,它只是删除作为终结回调的 data 参数接收的原生实例。

Typically when wrapping a class instance, a finalize callback should be provided that simply deletes the native instance that is received as the data argument to the finalize callback.

可选的返回引用最初是弱引用,这意味着它的引用计数为 0。通常,在需要实例保持有效的异步操作期间,此引用计数会临时增加。

The optional returned reference is initially a weak reference, meaning it has a reference count of 0. Typically this reference count would be incremented temporarily during async operations that require the instance to remain valid.

警告:可选的返回引用(如果获得)应仅通过 napi_delete_reference 删除以响应最终回调调用。如果在此之前删除它,则可能永远不会调用 finalize 回调。因此,在获取引用时,还需要一个 finalize 回调,以便能够正确处理引用。

Caution: The optional returned reference (if obtained) should be deleted via napi_delete_reference ONLY in response to the finalize callback invocation. If it is deleted before then, then the finalize callback may never be invoked. Therefore, when obtaining a reference a finalize callback is also required in order to enable correct disposal of the reference.

终结器回调可能会被延迟,留下一个窗口,其中对象已被垃圾收集(并且弱引用无效)但尚未调用终结器。在 napi_wrap() 返回的弱引用上使用 napi_get_reference_value() 时,你仍应处理空结果。

Finalizer callbacks may be deferred, leaving a window where the object has been garbage collected (and the weak reference is invalid) but the finalizer hasn't been called yet. When using napi_get_reference_value() on weak references returned by napi_wrap(), you should still handle an empty result.

对对象再次调用 napi_wrap() 将返回错误。要将另一个原生实例与对象相关联,请先使用 napi_remove_wrap()

Calling napi_wrap() a second time on an object will return an error. To associate another native instance with the object, use napi_remove_wrap() first.

napi_unwrap#

napi_status napi_unwrap(napi_env env,
                        napi_value js_object,
                        void** result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] js_object:与原生实例关联的对象。

    [in] js_object: The object associated with the native instance.

  • [out] result:指向封装的原生实例的指针。

    [out] result: Pointer to the wrapped native instance.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

使用 napi_wrap() 检索先前封装在 JavaScript 对象中的原生实例。

Retrieves a native instance that was previously wrapped in a JavaScript object using napi_wrap().

当 JavaScript 代码调用类上的方法或属性访问器时,将调用相应的 napi_callback。如果回调用于实例方法或访问器,则回调的 this 参数是封装器对象;然后可以通过在封装对象上调用 napi_unwrap() 来获得作为调用目标的封装 C++ 实例。

When JavaScript code invokes a method or property accessor on the class, the corresponding napi_callback is invoked. If the callback is for an instance method or accessor, then the this argument to the callback is the wrapper object; the wrapped C++ instance that is the target of the call can be obtained then by calling napi_unwrap() on the wrapper object.

napi_remove_wrap#

napi_status napi_remove_wrap(napi_env env,
                             napi_value js_object,
                             void** result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] js_object:与原生实例关联的对象。

    [in] js_object: The object associated with the native instance.

  • [out] result:指向封装的原生实例的指针。

    [out] result: Pointer to the wrapped native instance.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

使用 napi_wrap() 检索先前封装在 JavaScript 对象 js_object 中的原生实例并移除封装。如果 finalize 回调与封装相关联,则当 JavaScript 对象被垃圾回收时将不再调用它。

Retrieves a native instance that was previously wrapped in the JavaScript object js_object using napi_wrap() and removes the wrapping. If a finalize callback was associated with the wrapping, it will no longer be called when the JavaScript object becomes garbage-collected.

napi_type_tag_object#

napi_status napi_type_tag_object(napi_env env,
                                 napi_value js_object,
                                 const napi_type_tag* type_tag); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] js_object:要标记的 JavaScript 对象或 外部的

    [in] js_object: The JavaScript object or external to be marked.

  • [in] type_tag:要标记对象的标签。

    [in] type_tag: The tag with which the object is to be marked.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

type_tag 指针的值与 JavaScript 对象或 外部的 相关联。然后可以使用 napi_check_object_type_tag() 将附加到对象的标签与插件拥有的标签进行比较,以确保对象具有正确的类型。

Associates the value of the type_tag pointer with the JavaScript object or external. napi_check_object_type_tag() can then be used to compare the tag that was attached to the object with one owned by the addon to ensure that the object has the right type.

如果对象已经有关联的类型标签,此 API 将返回 napi_invalid_arg

If the object already has an associated type tag, this API will return napi_invalid_arg.

napi_check_object_type_tag#

napi_status napi_check_object_type_tag(napi_env env,
                                       napi_value js_object,
                                       const napi_type_tag* type_tag,
                                       bool* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] js_object:要检查其类型标记的 JavaScript 对象或 外部的

    [in] js_object: The JavaScript object or external whose type tag to examine.

  • [in] type_tag:用于比较在对象上找到的任何标签的标签。

    [in] type_tag: The tag with which to compare any tag found on the object.

  • [out] result:给定的类型标签是否与对象上的类型标签匹配。如果在对象上未找到类型标记,也会返回 false

    [out] result: Whether the type tag given matched the type tag on the object. false is also returned if no type tag was found on the object.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

将作为 type_tag 给出的指针与 js_object 上可以找到的任何指针进行比较。如果在 js_object 上没有找到标签,或者如果找到标签但它与 type_tag 不匹配,则 result 设置为 false。如果找到标签并且它与 type_tag 匹配,则将 result 设置为 true

Compares the pointer given as type_tag with any that can be found on js_object. If no tag is found on js_object or, if a tag is found but it does not match type_tag, then result is set to false. If a tag is found and it matches type_tag, then result is set to true.

napi_add_finalizer#

napi_status napi_add_finalizer(napi_env env,
                               napi_value js_object,
                               void* finalize_data,
                               napi_finalize finalize_cb,
                               void* finalize_hint,
                               napi_ref* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] js_object:原生数据将附加到的 JavaScript 对象。

    [in] js_object: The JavaScript object to which the native data will be attached.

  • [in] finalize_data:要传递给 finalize_cb 的可选数据。

    [in] finalize_data: Optional data to be passed to finalize_cb.

  • [in] finalize_cb:当 JavaScript 对象被垃圾回收时,将用于释放原生数据的原生回调。napi_finalize 提供了更多详细信息。

    [in] finalize_cb: Native callback that will be used to free the native data when the JavaScript object has been garbage-collected. napi_finalize provides more details.

  • [in] finalize_hint:传递给完成回调的可选上下文提示。

    [in] finalize_hint: Optional contextual hint that is passed to the finalize callback.

  • [out] result:对 JavaScript 对象的可选引用。

    [out] result: Optional reference to the JavaScript object.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

添加 napi_finalize 回调,当 js_object 中的 JavaScript 对象被垃圾回收时调用。

Adds a napi_finalize callback which will be called when the JavaScript object in js_object has been garbage-collected.

可以在单个 JavaScript 对象上多次调用此 API。

This API can be called multiple times on a single JavaScript object.

警告:可选的返回引用(如果获得)应仅通过 napi_delete_reference 删除以响应最终回调调用。如果在此之前删除它,则可能永远不会调用 finalize 回调。因此,在获取引用时,还需要一个 finalize 回调,以便能够正确处理引用。

Caution: The optional returned reference (if obtained) should be deleted via napi_delete_reference ONLY in response to the finalize callback invocation. If it is deleted before then, then the finalize callback may never be invoked. Therefore, when obtaining a reference a finalize callback is also required in order to enable correct disposal of the reference.

node_api_post_finalizer#

稳定性: 1 - 实验性的

Stability: 1 - Experimental

napi_status node_api_post_finalizer(napi_env env,
                                    napi_finalize finalize_cb,
                                    void* finalize_data,
                                    void* finalize_hint); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] finalize_cb:当 JavaScript 对象被垃圾回收时,将用于释放原生数据的原生回调。napi_finalize 提供了更多详细信息。

    [in] finalize_cb: Native callback that will be used to free the native data when the JavaScript object has been garbage-collected. napi_finalize provides more details.

  • [in] finalize_data:要传递给 finalize_cb 的可选数据。

    [in] finalize_data: Optional data to be passed to finalize_cb.

  • [in] finalize_hint:传递给完成回调的可选上下文提示。

    [in] finalize_hint: Optional contextual hint that is passed to the finalize callback.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

安排在事件循环中异步调用 napi_finalize 回调。

Schedules a napi_finalize callback to be called asynchronously in the event loop.

通常,当 GC(垃圾收集器)收集对象时,会调用终结器。届时,调用任何可能导致 GC 状态发生变化的 Node-API 将被禁用,并使 Node.js 崩溃。

Normally, finalizers are called while the GC (garbage collector) collects objects. At that point calling any Node-API that may cause changes in the GC state will be disabled and will crash Node.js.

node_api_post_finalizer 通过允许附加组件将对此类 Node-API 的调用推迟到 GC 最终确定之外的时间点来帮助解决此限制。

node_api_post_finalizer helps to work around this limitation by allowing the add-on to defer calls to such Node-APIs to a point in time outside of the GC finalization.

简单的异步操作#

Simple asynchronous operations

插件模块通常需要利用 libuv 中的异步助手作为其实现的一部分。这允许他们安排异步执行的工作,以便他们的方法可以在工作完成之前返回。这使他们能够避免阻止 Node.js 应用的整体执行。

Addon modules often need to leverage async helpers from libuv as part of their implementation. This allows them to schedule work to be executed asynchronously so that their methods can return in advance of the work being completed. This allows them to avoid blocking overall execution of the Node.js application.

Node-API 为这些支持功能提供了一个 ABI 稳定的接口,涵盖了最常见的异步用例。

Node-API provides an ABI-stable interface for these supporting functions which covers the most common asynchronous use cases.

Node-API 定义了用于管理异步工作者的 napi_async_work 结构。使用 napi_create_async_worknapi_delete_async_work 创建/删除实例。

Node-API defines the napi_async_work structure which is used to manage asynchronous workers. Instances are created/deleted with napi_create_async_work and napi_delete_async_work.

executecomplete 回调函数将分别在执行程序准备好执行和完成任务时调用。

The execute and complete callbacks are functions that will be invoked when the executor is ready to execute and when it completes its task respectively.

execute 函数应避免进行任何可能导致 JavaScript 执行或与 JavaScript 对象交互的 Node-API 调用。大多数情况下,任何需要进行 Node-API 调用的代码都应该在 complete 回调中进行。避免在执行回调中使用 napi_env 参数,因为它可能会执行 JavaScript。

The execute function should avoid making any Node-API calls that could result in the execution of JavaScript or interaction with JavaScript objects. Most often, any code that needs to make Node-API calls should be made in complete callback instead. Avoid using the napi_env parameter in the execute callback as it will likely execute JavaScript.

这些函数实现了以下接口:

These functions implement the following interfaces:

typedef void (*napi_async_execute_callback)(napi_env env,
                                            void* data);
typedef void (*napi_async_complete_callback)(napi_env env,
                                             napi_status status,
                                             void* data); 

调用这些方法时,传递的 data 参数将是传递给 napi_create_async_work 调用的插件提供的 void* 数据。

When these methods are invoked, the data parameter passed will be the addon-provided void* data that was passed into the napi_create_async_work call.

创建异步工作线程后,可以使用 napi_queue_async_work 函数排队等待执行:

Once created the async worker can be queued for execution using the napi_queue_async_work function:

napi_status napi_queue_async_work(napi_env env,
                                  napi_async_work work); 

如果需要在工作开始执行之前取消工作,则可以使用 napi_cancel_async_work

napi_cancel_async_work can be used if the work needs to be cancelled before the work has started execution.

调用 napi_cancel_async_work 后,将调用状态值为 napi_cancelledcomplete 回调。在 complete 回调调用之前不应删除该工作,即使它已被取消。

After calling napi_cancel_async_work, the complete callback will be invoked with a status value of napi_cancelled. The work should not be deleted before the complete callback invocation, even when it was cancelled.

napi_create_async_work#

napi_status napi_create_async_work(napi_env env,
                                   napi_value async_resource,
                                   napi_value async_resource_name,
                                   napi_async_execute_callback execute,
                                   napi_async_complete_callback complete,
                                   void* data,
                                   napi_async_work* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] async_resource:与将传递给可能的 async_hooks init 钩子 的异步工作关联的可选对象。

    [in] async_resource: An optional object associated with the async work that will be passed to possible async_hooks init hooks.

  • [in] async_resource_name:为 async_hooks API 公开的诊断信息提供的资源类型的标识符。

    [in] async_resource_name: Identifier for the kind of resource that is being provided for diagnostic information exposed by the async_hooks API.

  • [in] execute:应调用以异步执行逻辑的原生函数。给定的函数从工作池线程调用,可以与主事件循环线程并行执行。

    [in] execute: The native function which should be called to execute the logic asynchronously. The given function is called from a worker pool thread and can execute in parallel with the main event loop thread.

  • [in] complete:异步逻辑完成或取消时将调用的原生函数。从主事件循环线程调用给定的函数。napi_async_complete_callback 提供了更多详细信息。

    [in] complete: The native function which will be called when the asynchronous logic is completed or is cancelled. The given function is called from the main event loop thread. napi_async_complete_callback provides more details.

  • [in] data:用户提供的数据上下文。这将被传递回执行和完成功能。

    [in] data: User-provided data context. This will be passed back into the execute and complete functions.

  • [out] resultnapi_async_work* 是新创建的异步工作的句柄。

    [out] result: napi_async_work* which is the handle to the newly created async work.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 分配用于异步执行逻辑的工作对象。一旦不再需要该工作,应使用 napi_delete_async_work 将其释放。

This API allocates a work object that is used to execute logic asynchronously. It should be freed using napi_delete_async_work once the work is no longer required.

async_resource_name 应该是一个以 null 结尾的 UTF-8 编码字符串。

async_resource_name should be a null-terminated, UTF-8-encoded string.

async_resource_name 标识符由用户提供,应该代表正在执行的异步工作的类型。还建议将命名空间应用于标识符,例如 通过包含模块名称。有关详细信息,请参阅 async_hooks 文档

The async_resource_name identifier is provided by the user and should be representative of the type of async work being performed. It is also recommended to apply namespacing to the identifier, e.g. by including the module name. See the async_hooks documentation for more information.

napi_delete_async_work#

napi_status napi_delete_async_work(napi_env env,
                                   napi_async_work work); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] work:调用 napi_create_async_work 返回的句柄。

    [in] work: The handle returned by the call to napi_create_async_work.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 释放先前分配的工作对象。

This API frees a previously allocated work object.

即使存在挂起的 JavaScript 异常,也可以调用此 API。

This API can be called even if there is a pending JavaScript exception.

napi_queue_async_work#

napi_status napi_queue_async_work(napi_env env,
                                  napi_async_work work); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] work:调用 napi_create_async_work 返回的句柄。

    [in] work: The handle returned by the call to napi_create_async_work.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 请求安排执行先前分配的工作。成功返回后,不得使用相同的 napi_async_work 项再次调用此 API,否则结果将不确定。

This API requests that the previously allocated work be scheduled for execution. Once it returns successfully, this API must not be called again with the same napi_async_work item or the result will be undefined.

napi_cancel_async_work#

napi_status napi_cancel_async_work(napi_env env,
                                   napi_async_work work); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] work:调用 napi_create_async_work 返回的句柄。

    [in] work: The handle returned by the call to napi_create_async_work.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

如果尚未启动,此 API 会取消排队的工作。如果已经开始执行,则无法取消,返回 napi_generic_failure。如果成功,将调用 complete 回调,状态值为 napi_cancelled。在 complete 回调调用之前不应删除该工作,即使它已成功取消。

This API cancels queued work if it has not yet been started. If it has already started executing, it cannot be cancelled and napi_generic_failure will be returned. If successful, the complete callback will be invoked with a status value of napi_cancelled. The work should not be deleted before the complete callback invocation, even if it has been successfully cancelled.

即使存在挂起的 JavaScript 异常,也可以调用此 API。

This API can be called even if there is a pending JavaScript exception.

自定义异步操作#

Custom asynchronous operations

上面简单的异步工作 API 可能并不适用于所有场景。使用任何其他异步机制时,需要以下 API 来确保运行时正确跟踪异步操作。

The simple asynchronous work APIs above may not be appropriate for every scenario. When using any other asynchronous mechanism, the following APIs are necessary to ensure an asynchronous operation is properly tracked by the runtime.

napi_async_init#

napi_status napi_async_init(napi_env env,
                            napi_value async_resource,
                            napi_value async_resource_name,
                            napi_async_context* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] async_resource:与异步工作关联的对象,将传递给可能的 async_hooks init 钩子 并可由 async_hooks.executionAsyncResource() 访问。

    [in] async_resource: Object associated with the async work that will be passed to possible async_hooks init hooks and can be accessed by async_hooks.executionAsyncResource().

  • [in] async_resource_name:为 async_hooks API 公开的诊断信息提供的资源类型的标识符。

    [in] async_resource_name: Identifier for the kind of resource that is being provided for diagnostic information exposed by the async_hooks API.

  • [out] result:初始化的异步上下文。

    [out] result: The initialized async context.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

async_resource 对象需要保持活动状态直到 napi_async_destroy 才能使 async_hooks 相关 API 正常运行。为了保持与之前版本的 ABI 兼容性,napi_async_context 没有维护对 async_resource 对象的强引用,以避免引入导致内存泄漏。但是,如果 async_resourcenapi_async_contextnapi_async_destroy 销毁之前被 JavaScript 引擎垃圾回收,那么在使用 AsyncLocalStorage API 时调用 napi_async_context 相关 API(如 napi_open_callback_scopenapi_make_callback)可能会导致异步上下文丢失等问题。

The async_resource object needs to be kept alive until napi_async_destroy to keep async_hooks related API acts correctly. In order to retain ABI compatibility with previous versions, napi_async_contexts are not maintaining the strong reference to the async_resource objects to avoid introducing causing memory leaks. However, if the async_resource is garbage collected by JavaScript engine before the napi_async_context was destroyed by napi_async_destroy, calling napi_async_context related APIs like napi_open_callback_scope and napi_make_callback can cause problems like loss of async context when using the AsyncLocalStorage API.

为了保持与以前版本的 ABI 兼容性,为 async_resource 传递 NULL 不会导致错误。但是,不建议这样做,因为这会导致 async_hooks init 钩子async_hooks.executionAsyncResource() 出现不良行为,因为底层 async_hooks 实现现在需要该资源,以便提供异步回调之间的链接。

In order to retain ABI compatibility with previous versions, passing NULL for async_resource does not result in an error. However, this is not recommended as this will result in undesirable behavior with async_hooks init hooks and async_hooks.executionAsyncResource() as the resource is now required by the underlying async_hooks implementation in order to provide the linkage between async callbacks.

napi_async_destroy#

napi_status napi_async_destroy(napi_env env,
                               napi_async_context async_context); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] async_context:要销毁的异步上下文。

    [in] async_context: The async context to be destroyed.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

即使存在挂起的 JavaScript 异常,也可以调用此 API。

This API can be called even if there is a pending JavaScript exception.

napi_make_callback#

NAPI_EXTERN napi_status napi_make_callback(napi_env env,
                                           napi_async_context async_context,
                                           napi_value recv,
                                           napi_value func,
                                           size_t argc,
                                           const napi_value* argv,
                                           napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] async_context:调用回调的异步操作的上下文。这通常应该是以前从 napi_async_init 获得的值。为了保持与以前版本的 ABI 兼容性,为 async_context 传递 NULL 不会导致错误。但是,这会导致异步钩子的错误操作。潜在问题包括使用 AsyncLocalStorage API 时丢失异步上下文。

    [in] async_context: Context for the async operation that is invoking the callback. This should normally be a value previously obtained from napi_async_init. In order to retain ABI compatibility with previous versions, passing NULL for async_context does not result in an error. However, this results in incorrect operation of async hooks. Potential issues include loss of async context when using the AsyncLocalStorage API.

  • [in] recv:传递给被调用函数的 this 值。

    [in] recv: The this value passed to the called function.

  • [in] funcnapi_value 表示要调用的 JavaScript 函数。

    [in] func: napi_value representing the JavaScript function to be invoked.

  • [in] argcargv 数组中的元素数。

    [in] argc: The count of elements in the argv array.

  • [in] argv:JavaScript 值数组 napi_value 表示函数的参数。如果 argc 为零,则可以通过传入 NULL 来省略此参数。

    [in] argv: Array of JavaScript values as napi_value representing the arguments to the function. If argc is zero this parameter may be omitted by passing in NULL.

  • [out] resultnapi_value 表示返回的 JavaScript 对象。

    [out] result: napi_value representing the JavaScript object returned.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此方法允许从原生附加组件调用 JavaScript 函数对象。这个 API 类似于 napi_call_function。但是,它用于在从异步操作返回后(当堆栈上没有其他脚本时)从原生代码调用回 JavaScript。它是 node::MakeCallback 的一个相当简单的封装器。

This method allows a JavaScript function object to be called from a native add-on. This API is similar to napi_call_function. However, it is used to call from native code back into JavaScript after returning from an async operation (when there is no other script on the stack). It is a fairly simple wrapper around node::MakeCallback.

请注意,不必在 napi_async_complete_callback 中使用 napi_make_callback;在这种情况下,回调的异步上下文已经设置好,因此直接调用 napi_call_function 就足够且合适了。实现不使用 napi_create_async_work 的自定义异步行为时,可能需要使用 napi_make_callback 函数。

Note it is not necessary to use napi_make_callback from within a napi_async_complete_callback; in that situation the callback's async context has already been set up, so a direct call to napi_call_function is sufficient and appropriate. Use of the napi_make_callback function may be required when implementing custom async behavior that does not use napi_create_async_work.

在回调期间由 JavaScript 在微任务队列上安排的任何 process.nextTick 或 Promises 在返回到 C/C++ 之前运行。

Any process.nextTicks or Promises scheduled on the microtask queue by JavaScript during the callback are ran before returning back to C/C++.

napi_open_callback_scope#

NAPI_EXTERN napi_status napi_open_callback_scope(napi_env env,
                                                 napi_value resource_object,
                                                 napi_async_context context,
                                                 napi_callback_scope* result) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] resource_object:与将传递给可能的 async_hooks init 钩子 的异步工作关联的对象。此参数已被弃用,并在运行时被忽略。请改用 napi_async_init 中的 async_resource 参数。

    [in] resource_object: An object associated with the async work that will be passed to possible async_hooks init hooks. This parameter has been deprecated and is ignored at runtime. Use the async_resource parameter in napi_async_init instead.

  • [in] context:调用回调的异步操作的上下文。这应该是之前从 napi_async_init 获得的值。

    [in] context: Context for the async operation that is invoking the callback. This should be a value previously obtained from napi_async_init.

  • [out] result:新创建的范围。

    [out] result: The newly created scope.

在某些情况下(例如,解决 promise),在进行某些 Node-API 调用时,有必要具有与回调关联的等效范围。如果堆栈上没有其他脚本,则可以使用 napi_open_callback_scopenapi_close_callback_scope 函数打开/关闭所需的范围。

There are cases (for example, resolving promises) where it is necessary to have the equivalent of the scope associated with a callback in place when making certain Node-API calls. If there is no other script on the stack the napi_open_callback_scope and napi_close_callback_scope functions can be used to open/close the required scope.

napi_close_callback_scope#

NAPI_EXTERN napi_status napi_close_callback_scope(napi_env env,
                                                  napi_callback_scope scope) 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] scope:要关闭的范围。

    [in] scope: The scope to be closed.

即使存在挂起的 JavaScript 异常,也可以调用此 API。

This API can be called even if there is a pending JavaScript exception.

版本管理#

Version management

napi_get_node_version#

typedef struct {
  uint32_t major;
  uint32_t minor;
  uint32_t patch;
  const char* release;
} napi_node_version;

napi_status napi_get_node_version(napi_env env,
                                  const napi_node_version** version); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [out] version:指向 Node.js 本身版本信息的指针。

    [out] version: A pointer to version information for Node.js itself.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此函数用当前运行的 Node.js 的主要、次要和补丁版本填充 version 结构,并用 process.release.name 的值填充 release 字段。

This function fills the version struct with the major, minor, and patch version of Node.js that is currently running, and the release field with the value of process.release.name.

返回的缓冲区是静态分配的,不需要释放。

The returned buffer is statically allocated and does not need to be freed.

napi_get_version#

napi_status napi_get_version(napi_env env,
                             uint32_t* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [out] result:支持的最高版本的 Node-API。

    [out] result: The highest version of Node-API supported.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 返回 Node.js 运行时支持的最高 Node-API 版本。Node-API 计划是附加的,这样较新版本的 Node.js 可能会支持额外的 API 函数。为了允许插件在使用支持它的 Node.js 版本运行时使用更新的功能,同时在使用不支持它的 Node.js 版本运行时提供回退行为:

This API returns the highest Node-API version supported by the Node.js runtime. Node-API is planned to be additive such that newer releases of Node.js may support additional API functions. In order to allow an addon to use a newer function when running with versions of Node.js that support it, while providing fallback behavior when running with Node.js versions that don't support it:

  • 调用 napi_get_version() 以确定 API 是否可用。

    Call napi_get_version() to determine if the API is available.

  • 如果可用,使用 uv_dlsym() 动态加载指向函数的指针。

    If available, dynamically load a pointer to the function using uv_dlsym().

  • 使用动态加载的指针来调用函数。

    Use the dynamically loaded pointer to invoke the function.

  • 如果该函数不可用,请提供不使用该函数的替代实现。

    If the function is not available, provide an alternate implementation that does not use the function.

内存管理#

Memory management

napi_adjust_external_memory#

NAPI_EXTERN napi_status napi_adjust_external_memory(napi_env env,
                                                    int64_t change_in_bytes,
                                                    int64_t* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] change_in_bytes:由 JavaScript 对象保持活动状态的外部分配内存的变化。

    [in] change_in_bytes: The change in externally allocated memory that is kept alive by JavaScript objects.

  • [out] result:调整值

    [out] result: The adjusted value

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此函数向 V8 指示由 JavaScript 对象保持活动状态的外部分配内存量(即,指向其自身由原生插件分配的内存的 JavaScript 对象)。注册外部分配的内存将比其他方式更频繁地触发全局垃圾回收。

This function gives V8 an indication of the amount of externally allocated memory that is kept alive by JavaScript objects (i.e. a JavaScript object that points to its own memory allocated by a native addon). Registering externally allocated memory will trigger global garbage collections more often than it would otherwise.

Promise#

Node-API 提供了创建 Promise 对象的工具,如 ECMA 规范的 第 25.4 节 中所述。它将 promise 实现为一对对象。当 napi_create_promise() 创建 promise 时,将创建 "deferred" 对象并与 Promise 一起返回。延迟对象绑定到创建的 Promise,是使用 napi_resolve_deferred()napi_reject_deferred() 解析或拒绝 Promise 的唯一方法。napi_create_promise() 创建的延迟对象由 napi_resolve_deferred()napi_reject_deferred() 释放。Promise 对象可能会返回到 JavaScript,以便以通常的方式使用它。

Node-API provides facilities for creating Promise objects as described in Section 25.4 of the ECMA specification. It implements promises as a pair of objects. When a promise is created by napi_create_promise(), a "deferred" object is created and returned alongside the Promise. The deferred object is bound to the created Promise and is the only means to resolve or reject the Promise using napi_resolve_deferred() or napi_reject_deferred(). The deferred object that is created by napi_create_promise() is freed by napi_resolve_deferred() or napi_reject_deferred(). The Promise object may be returned to JavaScript where it can be used in the usual fashion.

例如,要创建一个 promise 并将其传递给异步 worker:

For example, to create a promise and pass it to an asynchronous worker:

napi_deferred deferred;
napi_value promise;
napi_status status;

// Create the promise.
status = napi_create_promise(env, &deferred, &promise);
if (status != napi_ok) return NULL;

// Pass the deferred to a function that performs an asynchronous action.
do_something_asynchronous(deferred);

// Return the promise to JS
return promise; 

上面的函数 do_something_asynchronous() 将执行它的异步操作,然后它会解析或拒绝 deferred,从而结束 promise 并释放 deferred:

The above function do_something_asynchronous() would perform its asynchronous action and then it would resolve or reject the deferred, thereby concluding the promise and freeing the deferred:

napi_deferred deferred;
napi_value undefined;
napi_status status;

// Create a value with which to conclude the deferred.
status = napi_get_undefined(env, &undefined);
if (status != napi_ok) return NULL;

// Resolve or reject the promise associated with the deferred depending on
// whether the asynchronous action succeeded.
if (asynchronous_action_succeeded) {
  status = napi_resolve_deferred(env, deferred, undefined);
} else {
  status = napi_reject_deferred(env, deferred, undefined);
}
if (status != napi_ok) return NULL;

// At this point the deferred has been freed, so we should assign NULL to it.
deferred = NULL; 

napi_create_promise#

napi_status napi_create_promise(napi_env env,
                                napi_deferred* deferred,
                                napi_value* promise); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [out] deferred:一个新创建的延迟对象,稍后可以传递给 napi_resolve_deferred()napi_reject_deferred() 以解析 resp。拒绝相关的 promise。

    [out] deferred: A newly created deferred object which can later be passed to napi_resolve_deferred() or napi_reject_deferred() to resolve resp. reject the associated promise.

  • [out] promise:与延迟对象关联的 JavaScript promise。

    [out] promise: The JavaScript promise associated with the deferred object.

如果 API 成功,则返回 napi_ok

Returns napi_ok if the API succeeded.

此 API 创建一个延迟对象和一个 JavaScript promise。

This API creates a deferred object and a JavaScript promise.

napi_resolve_deferred#

napi_status napi_resolve_deferred(napi_env env,
                                  napi_deferred deferred,
                                  napi_value resolution); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] deferred:要解析其关联 promise 的延迟对象。

    [in] deferred: The deferred object whose associated promise to resolve.

  • [in] resolution:用于解决 promise 的值。

    [in] resolution: The value with which to resolve the promise.

此 API 通过与其关联的延迟对象来解析 JavaScript promise。因此,它只能用于解析相应延迟对象可用的 JavaScript promise。这实际上意味着 promise 必须是使用 napi_create_promise() 创建的,并且必须保留从该调用返回的延迟对象才能传递给此 API。

This API resolves a JavaScript promise by way of the deferred object with which it is associated. Thus, it can only be used to resolve JavaScript promises for which the corresponding deferred object is available. This effectively means that the promise must have been created using napi_create_promise() and the deferred object returned from that call must have been retained in order to be passed to this API.

延迟对象在成功完成后被释放。

The deferred object is freed upon successful completion.

napi_reject_deferred#

napi_status napi_reject_deferred(napi_env env,
                                 napi_deferred deferred,
                                 napi_value rejection); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] deferred:要解析其关联 promise 的延迟对象。

    [in] deferred: The deferred object whose associated promise to resolve.

  • [in] rejection:用于拒绝 promise 的值。

    [in] rejection: The value with which to reject the promise.

此 API 通过与其关联的延迟对象拒绝 JavaScript promise。因此,它只能用于拒绝相应延迟对象可用的 JavaScript promise。这实际上意味着 promise 必须是使用 napi_create_promise() 创建的,并且必须保留从该调用返回的延迟对象才能传递给此 API。

This API rejects a JavaScript promise by way of the deferred object with which it is associated. Thus, it can only be used to reject JavaScript promises for which the corresponding deferred object is available. This effectively means that the promise must have been created using napi_create_promise() and the deferred object returned from that call must have been retained in order to be passed to this API.

延迟对象在成功完成后被释放。

The deferred object is freed upon successful completion.

napi_is_promise#

napi_status napi_is_promise(napi_env env,
                            napi_value value,
                            bool* is_promise); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] value:要检查的值

    [in] value: The value to examine

  • [out] is_promise:表示 promise 是否为原生 promise 对象(即底层引擎创建的 promise 对象)的标志。

    [out] is_promise: Flag indicating whether promise is a native promise object (that is, a promise object created by the underlying engine).

脚本执行#

Script execution

Node-API 提供了一个 API,用于使用底层 JavaScript 引擎执行包含 JavaScript 的字符串。

Node-API provides an API for executing a string containing JavaScript using the underlying JavaScript engine.

napi_run_script#

NAPI_EXTERN napi_status napi_run_script(napi_env env,
                                        napi_value script,
                                        napi_value* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] script:包含要执行的脚本的 JavaScript 字符串。

    [in] script: A JavaScript string containing the script to execute.

  • [out] result:执行脚本产生的值。

    [out] result: The value resulting from having executed the script.

此函数执行一串 JavaScript 代码并返回其结果,但有以下注意事项:

This function executes a string of JavaScript code and returns its result with the following caveats:

  • eval 不同,此函数不允许脚本访问当前词法范围,因此也不允许访问 模块作用域,这意味着像 require 这样的伪全局变量将不可用。

    Unlike eval, this function does not allow the script to access the current lexical scope, and therefore also does not allow to access the module scope, meaning that pseudo-globals such as require will not be available.

  • 该脚本可以访问 全局作用域。脚本中的函数和 var 声明将添加到 global 对象中。使用 letconst 进行的变量声明将在全局可见,但不会添加到 global 对象中。

    The script can access the global scope. Function and var declarations in the script will be added to the global object. Variable declarations made using let and const will be visible globally, but will not be added to the global object.

  • this 的值是脚本中的 global

    The value of this is global within the script.

libuv 事件循环#

libuv event loop

Node-API 提供了一个函数,用于获取与特定 napi_env 关联的当前事件循环。

Node-API provides a function for getting the current event loop associated with a specific napi_env.

napi_get_uv_event_loop#

NAPI_EXTERN napi_status napi_get_uv_event_loop(napi_env env,
                                               struct uv_loop_s** loop); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [out] loop:当前的 libuv 循环实例。

    [out] loop: The current libuv loop instance.

异步线程安全函数调用#

Asynchronous thread-safe function calls

JavaScript 函数通常只能从原生插件的主线程调用。如果插件创建了额外的线程,则不得从这些线程调用需要 napi_envnapi_valuenapi_ref 的 Node-API 函数。

JavaScript functions can normally only be called from a native addon's main thread. If an addon creates additional threads, then Node-API functions that require a napi_env, napi_value, or napi_ref must not be called from those threads.

当插件有额外的线程并且需要根据这些线程完成的处理调用 JavaScript 函数时,这些线程必须与插件的主线程通信,以便主线程可以代表它们调用 JavaScript 函数。线程安全函数 API 提供了一种简单的方法来执行此操作。

When an addon has additional threads and JavaScript functions need to be invoked based on the processing completed by those threads, those threads must communicate with the addon's main thread so that the main thread can invoke the JavaScript function on their behalf. The thread-safe function APIs provide an easy way to do this.

这些 API 提供了类型 napi_threadsafe_function 以及创建、销毁和调用该类型对象的 API。napi_create_threadsafe_function() 创建对 napi_value 的持久引用,该引用包含可从多个线程调用的 JavaScript 函数。调用异步发生。这意味着调用 JavaScript 回调的值将被放置在一个队列中,并且对于队列中的每个值,最终将调用 JavaScript 函数。

These APIs provide the type napi_threadsafe_function as well as APIs to create, destroy, and call objects of this type. napi_create_threadsafe_function() creates a persistent reference to a napi_value that holds a JavaScript function which can be called from multiple threads. The calls happen asynchronously. This means that values with which the JavaScript callback is to be called will be placed in a queue, and, for each value in the queue, a call will eventually be made to the JavaScript function.

创建 napi_threadsafe_function 后,可以提供 napi_finalize 回调。当线程安全函数即将被销毁时,将在主线程上调用此回调。它接收构造期间给出的上下文和最终数据,并提供在线程之后进行清理的机会,例如 通过调用 uv_thread_join()。除了主循环线程之外,在 finalize 回调完成后,没有线程应该使用线程安全函数。

Upon creation of a napi_threadsafe_function a napi_finalize callback can be provided. This callback will be invoked on the main thread when the thread-safe function is about to be destroyed. It receives the context and the finalize data given during construction, and provides an opportunity for cleaning up after the threads e.g. by calling uv_thread_join(). Aside from the main loop thread, no threads should be using the thread-safe function after the finalize callback completes.

在调用 napi_create_threadsafe_function() 期间给出的 context 可以从调用 napi_get_threadsafe_function_context() 的任何线程中检索。

The context given during the call to napi_create_threadsafe_function() can be retrieved from any thread with a call to napi_get_threadsafe_function_context().

调用线程安全的函数#

Calling a thread-safe function

napi_call_threadsafe_function() 可用于启动对 JavaScript 的调用。napi_call_threadsafe_function() 接受一个参数,该参数控制 API 是否以阻塞方式运行。如果设置为 napi_tsfn_nonblocking,API 将以非阻塞方式运行,如果队列已满则返回 napi_queue_full,从而阻止数据成功添加到队列中。如果设置为 napi_tsfn_blocking,API 将阻塞,直到队列中有可用空间。如果创建的线程安全函数的最大队列大小为 0,则 napi_call_threadsafe_function() 永远不会阻塞。

napi_call_threadsafe_function() can be used for initiating a call into JavaScript. napi_call_threadsafe_function() accepts a parameter which controls whether the API behaves blockingly. If set to napi_tsfn_nonblocking, the API behaves non-blockingly, returning napi_queue_full if the queue was full, preventing data from being successfully added to the queue. If set to napi_tsfn_blocking, the API blocks until space becomes available in the queue. napi_call_threadsafe_function() never blocks if the thread-safe function was created with a maximum queue size of 0.

不应从 JavaScript 线程使用 napi_tsfn_blocking 调用 napi_call_threadsafe_function(),因为如果队列已满,可能会导致 JavaScript 线程死锁。

napi_call_threadsafe_function() should not be called with napi_tsfn_blocking from a JavaScript thread, because, if the queue is full, it may cause the JavaScript thread to deadlock.

对 JavaScript 的实际调用由通过 call_js_cb 参数给出的回调控制。对于通过成功调用 napi_call_threadsafe_function() 放入队列中的每个值,在主线程上调用 call_js_cb 一次。如果没有给出这样的回调,将使用默认回调,并且生成的 JavaScript 调用将没有参数。call_js_cb 回调在其参数中接收要作为 napi_value 调用的 JavaScript 函数,以及创建 napi_threadsafe_function 时使用的 void* 上下文指针,以及由其中一个辅助线程创建的下一个数据指针。然后,回调可以使用诸如 napi_call_function() 之类的 API 来调用 JavaScript。

The actual call into JavaScript is controlled by the callback given via the call_js_cb parameter. call_js_cb is invoked on the main thread once for each value that was placed into the queue by a successful call to napi_call_threadsafe_function(). If such a callback is not given, a default callback will be used, and the resulting JavaScript call will have no arguments. The call_js_cb callback receives the JavaScript function to call as a napi_value in its parameters, as well as the void* context pointer used when creating the napi_threadsafe_function, and the next data pointer that was created by one of the secondary threads. The callback can then use an API such as napi_call_function() to call into JavaScript.

回调也可以在 envcall_js_cb 都设置为 NULL 的情况下调用,以指示不再可能调用 JavaScript,而项目仍保留在可能需要释放的队列中。这通常发生在 Node.js 进程退出而线程安全功能仍处于活动状态时。

The callback may also be invoked with env and call_js_cb both set to NULL to indicate that calls into JavaScript are no longer possible, while items remain in the queue that may need to be freed. This normally occurs when the Node.js process exits while there is a thread-safe function still active.

没有必要通过 napi_make_callback() 调用 JavaScript,因为 Node-API 在适合回调的上下文中运行 call_js_cb

It is not necessary to call into JavaScript via napi_make_callback() because Node-API runs call_js_cb in a context appropriate for callbacks.

在事件循环的每个周期中可以调用零个或多个排队项目。应用不应该依赖于特定的行为,除了随着时间的推移将进行调用回调的进度并且将调用事件之外。

Zero or more queued items may be invoked in each tick of the event loop. Applications should not depend on a specific behavior other than progress in invoking callbacks will be made and events will be invoked as time moves forward.

线程安全函数的引用计数#

Reference counting of thread-safe functions

napi_threadsafe_function 对象存在期间,可以将线程添加到 napi_threadsafe_function 对象或从中删除。因此,除了在创建时指定线程的初始数量外,还可以调用 napi_acquire_threadsafe_function 来指示新线程将开始使用线程安全函数。同样,可以调用 napi_release_threadsafe_function 来指示现有线程将停止使用线程安全函数。

Threads can be added to and removed from a napi_threadsafe_function object during its existence. Thus, in addition to specifying an initial number of threads upon creation, napi_acquire_threadsafe_function can be called to indicate that a new thread will start making use of the thread-safe function. Similarly, napi_release_threadsafe_function can be called to indicate that an existing thread will stop making use of the thread-safe function.

当使用该对象的每个线程调用 napi_release_threadsafe_function() 或收到 napi_closing 的返回状态以响应对 napi_call_threadsafe_function 的调用时,napi_threadsafe_function 对象将被销毁。在 napi_threadsafe_function 被销毁之前队列被清空。napi_release_threadsafe_function() 应该是与给定的 napi_threadsafe_function 一起进行的最后一次 API 调用,因为在调用完成后,无法保证 napi_threadsafe_function 仍然被分配。出于同样的原因,在收到 napi_closing 的返回值以响应对 napi_call_threadsafe_function 的调用后,不要使用线程安全函数。可以在传递给 napi_create_threadsafe_function()napi_finalize 回调中释放与 napi_threadsafe_function 关联的数据。napi_create_threadsafe_function 的参数 initial_thread_count 表示线程安全函数的初始获取次数,而不是在创建时多次调用 napi_acquire_threadsafe_function

napi_threadsafe_function objects are destroyed when every thread which uses the object has called napi_release_threadsafe_function() or has received a return status of napi_closing in response to a call to napi_call_threadsafe_function. The queue is emptied before the napi_threadsafe_function is destroyed. napi_release_threadsafe_function() should be the last API call made in conjunction with a given napi_threadsafe_function, because after the call completes, there is no guarantee that the napi_threadsafe_function is still allocated. For the same reason, do not use a thread-safe function after receiving a return value of napi_closing in response to a call to napi_call_threadsafe_function. Data associated with the napi_threadsafe_function can be freed in its napi_finalize callback which was passed to napi_create_threadsafe_function(). The parameter initial_thread_count of napi_create_threadsafe_function marks the initial number of acquisitions of the thread-safe functions, instead of calling napi_acquire_threadsafe_function multiple times at creation.

一旦使用 napi_threadsafe_function 的线程数达到零,则没有其他线程可以通过调用 napi_acquire_threadsafe_function() 开始使用它。事实上,除 napi_release_threadsafe_function() 之外的所有后续 API 调用都将返回错误值 napi_closing

Once the number of threads making use of a napi_threadsafe_function reaches zero, no further threads can start making use of it by calling napi_acquire_threadsafe_function(). In fact, all subsequent API calls associated with it, except napi_release_threadsafe_function(), will return an error value of napi_closing.

线程安全函数可以通过给 napi_release_threadsafe_function() 赋值 napi_tsfn_abort 来实现 "aborted"。这将导致除 napi_release_threadsafe_function() 之外与线程安全函数关联的所有后续 API 甚至在其引用计数达到零之前就返回 napi_closing。特别是,napi_call_threadsafe_function() 将返回 napi_closing,从而通知线程不再可能对线程安全函数进行异步调用。这可以用作终止线程的标准。从 napi_call_threadsafe_function() 接收到 napi_closing 的返回值后,线程不得再使用线程安全函数,因为不再保证会分配它。

The thread-safe function can be "aborted" by giving a value of napi_tsfn_abort to napi_release_threadsafe_function(). This will cause all subsequent APIs associated with the thread-safe function except napi_release_threadsafe_function() to return napi_closing even before its reference count reaches zero. In particular, napi_call_threadsafe_function() will return napi_closing, thus informing the threads that it is no longer possible to make asynchronous calls to the thread-safe function. This can be used as a criterion for terminating the thread. Upon receiving a return value of napi_closing from napi_call_threadsafe_function() a thread must not use the thread-safe function anymore because it is no longer guaranteed to be allocated.

决定是否保持进程运行#

Deciding whether to keep the process running

与 libuv 句柄类似,线程安全函数可以是 "referenced" 和 "unreferenced"。"referenced" 线程安全函数将导致创建它的线程上的事件循环保持活动状态,直到线程安全函数被销毁。相反,"unreferenced" 线程安全函数不会阻止事件循环退出。API napi_ref_threadsafe_functionnapi_unref_threadsafe_function 就是为此目的而存在的。

Similarly to libuv handles, thread-safe functions can be "referenced" and "unreferenced". A "referenced" thread-safe function will cause the event loop on the thread on which it is created to remain alive until the thread-safe function is destroyed. In contrast, an "unreferenced" thread-safe function will not prevent the event loop from exiting. The APIs napi_ref_threadsafe_function and napi_unref_threadsafe_function exist for this purpose.

napi_unref_threadsafe_function 既没有将线程安全函数标记为可以被销毁,也没有 napi_ref_threadsafe_function 阻止它被销毁。

Neither does napi_unref_threadsafe_function mark the thread-safe functions as able to be destroyed nor does napi_ref_threadsafe_function prevent it from being destroyed.

napi_create_threadsafe_function#

NAPI_EXTERN napi_status
napi_create_threadsafe_function(napi_env env,
                                napi_value func,
                                napi_value async_resource,
                                napi_value async_resource_name,
                                size_t max_queue_size,
                                size_t initial_thread_count,
                                void* thread_finalize_data,
                                napi_finalize thread_finalize_cb,
                                void* context,
                                napi_threadsafe_function_call_js call_js_cb,
                                napi_threadsafe_function* result); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] func:从另一个线程调用的可选 JavaScript 函数。如果 NULL 传递给 call_js_cb,则必须提供它。

    [in] func: An optional JavaScript function to call from another thread. It must be provided if NULL is passed to call_js_cb.

  • [in] async_resource:与将传递给可能的 async_hooks init 钩子 的异步工作关联的可选对象。

    [in] async_resource: An optional object associated with the async work that will be passed to possible async_hooks init hooks.

  • [in] async_resource_name:一个 JavaScript 字符串,用于为 async_hooks API 公开的诊断信息提供的资源类型提供标识符。

    [in] async_resource_name: A JavaScript string to provide an identifier for the kind of resource that is being provided for diagnostic information exposed by the async_hooks API.

  • [in] max_queue_size:队列的最大大小。0 为无限制。

    [in] max_queue_size: Maximum size of the queue. 0 for no limit.

  • [in] initial_thread_count:初始获取数,即初始线程数,包括将使用此函数的主线程。

    [in] initial_thread_count: The initial number of acquisitions, i.e. the initial number of threads, including the main thread, which will be making use of this function.

  • [in] thread_finalize_data:要传递给 thread_finalize_cb 的可选数据。

    [in] thread_finalize_data: Optional data to be passed to thread_finalize_cb.

  • [in] thread_finalize_cbnapi_threadsafe_function 被销毁时调用的可选函数。

    [in] thread_finalize_cb: Optional function to call when the napi_threadsafe_function is being destroyed.

  • [in] context:附加到生成的 napi_threadsafe_function 的可选数据。

    [in] context: Optional data to attach to the resulting napi_threadsafe_function.

  • [in] call_js_cb:可选回调调用 JavaScript 函数以响应不同线程上的调用。此回调将在主线程上调用。如果没有给出,JavaScript 函数将在没有参数的情况下调用,并将 undefined 作为其 this 值。napi_threadsafe_function_call_js 提供了更多详细信息。

    [in] call_js_cb: Optional callback which calls the JavaScript function in response to a call on a different thread. This callback will be called on the main thread. If not given, the JavaScript function will be called with no parameters and with undefined as its this value. napi_threadsafe_function_call_js provides more details.

  • [out] result:异步线程安全的 JavaScript 函数。

    [out] result: The asynchronous thread-safe JavaScript function.

变更历史:

Change History:

  • 实验性的(定义了 NAPI_EXPERIMENTAL):

    Experimental (NAPI_EXPERIMENTAL is defined):

    call_js_cb 中引发的未捕获异常将由 'uncaughtException' 事件处理,而不是被忽略。

    Uncaught exceptions thrown in call_js_cb are handled with the 'uncaughtException' event, instead of being ignored.

napi_get_threadsafe_function_context#

NAPI_EXTERN napi_status
napi_get_threadsafe_function_context(napi_threadsafe_function func,
                                     void** result); 
  • [in] func:为其检索上下文的线程安全函数。

    [in] func: The thread-safe function for which to retrieve the context.

  • [out] result:存储上下文的位置。

    [out] result: The location where to store the context.

可以从使用 func 的任何线程调用此 API。

This API may be called from any thread which makes use of func.

napi_call_threadsafe_function#

NAPI_EXTERN napi_status
napi_call_threadsafe_function(napi_threadsafe_function func,
                              void* data,
                              napi_threadsafe_function_call_mode is_blocking); 
  • [in] func:要调用的异步线程安全 JavaScript 函数。

    [in] func: The asynchronous thread-safe JavaScript function to invoke.

  • [in] data:通过创建线程安全 JavaScript 函数期间提供的回调 call_js_cb 发送到 JavaScript 的数据。

    [in] data: Data to send into JavaScript via the callback call_js_cb provided during the creation of the thread-safe JavaScript function.

  • [in] is_blocking:标志,其值可以是 napi_tsfn_blocking,表示如果队列已满,调用应该阻塞;也可以是 napi_tsfn_nonblocking,表示只要队列已满,调用就应该立即返回,状态为 napi_queue_full

    [in] is_blocking: Flag whose value can be either napi_tsfn_blocking to indicate that the call should block if the queue is full or napi_tsfn_nonblocking to indicate that the call should return immediately with a status of napi_queue_full whenever the queue is full.

不应从 JavaScript 线程使用 napi_tsfn_blocking 调用此 API,因为如果队列已满,可能会导致 JavaScript 线程死锁。

This API should not be called with napi_tsfn_blocking from a JavaScript thread, because, if the queue is full, it may cause the JavaScript thread to deadlock.

如果从任何线程调用 napi_release_threadsafe_function() 并将 abort 设置为 napi_tsfn_abort,则此 API 将返回 napi_closing。只有当 API 返回 napi_ok 时,该值才会添加到队列中。

This API will return napi_closing if napi_release_threadsafe_function() was called with abort set to napi_tsfn_abort from any thread. The value is only added to the queue if the API returns napi_ok.

可以从使用 func 的任何线程调用此 API。

This API may be called from any thread which makes use of func.

napi_acquire_threadsafe_function#

NAPI_EXTERN napi_status
napi_acquire_threadsafe_function(napi_threadsafe_function func); 
  • [in] func:开始使用异步线程安全的 JavaScript 函数。

    [in] func: The asynchronous thread-safe JavaScript function to start making use of.

线程应在将 func 传递给任何其他线程安全函数 API 以指示它将使用 func 之前调用此 API。这可以防止 func 在所有其他线程停止使用它时被销毁。

A thread should call this API before passing func to any other thread-safe function APIs to indicate that it will be making use of func. This prevents func from being destroyed when all other threads have stopped making use of it.

可以从将开始使用 func 的任何线程调用此 API。

This API may be called from any thread which will start making use of func.

napi_release_threadsafe_function#

NAPI_EXTERN napi_status
napi_release_threadsafe_function(napi_threadsafe_function func,
                                 napi_threadsafe_function_release_mode mode); 
  • [in] func:异步线程安全的 JavaScript 函数,其引用计数将减少。

    [in] func: The asynchronous thread-safe JavaScript function whose reference count to decrement.

  • [in] mode:其值可以是 napi_tsfn_release 的标志,表示当前线程将不再调用线程安全函数,或者是 napi_tsfn_abort,表示除了当前线程之外,没有其他线程应该进一步调用线程安全函数 功能。如果设置为 napi_tsfn_abort,对 napi_call_threadsafe_function() 的进一步调用将返回 napi_closing,并且不会将更多值放入队列中。

    [in] mode: Flag whose value can be either napi_tsfn_release to indicate that the current thread will make no further calls to the thread-safe function, or napi_tsfn_abort to indicate that in addition to the current thread, no other thread should make any further calls to the thread-safe function. If set to napi_tsfn_abort, further calls to napi_call_threadsafe_function() will return napi_closing, and no further values will be placed in the queue.

线程停止使用 func 时应调用此 API。在调用此 API 后将 func 传递给任何线程安全的 API 会产生未定义的结果,因为 func 可能已被销毁。

A thread should call this API when it stops making use of func. Passing func to any thread-safe APIs after having called this API has undefined results, as func may have been destroyed.

可以从任何将停止使用 func 的线程调用此 API。

This API may be called from any thread which will stop making use of func.

napi_ref_threadsafe_function#

NAPI_EXTERN napi_status
napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] func:要引用的线程安全函数。

    [in] func: The thread-safe function to reference.

此 API 用于指示在主线程上运行的事件循环在 func 被销毁之前不应退出。与 uv_ref 类似,它也是幂等的。

This API is used to indicate that the event loop running on the main thread should not exit until func has been destroyed. Similar to uv_ref it is also idempotent.

napi_unref_threadsafe_function 既没有将线程安全函数标记为可以被销毁,也没有 napi_ref_threadsafe_function 阻止它被销毁。napi_acquire_threadsafe_functionnapi_release_threadsafe_function 可用于该目的。

Neither does napi_unref_threadsafe_function mark the thread-safe functions as able to be destroyed nor does napi_ref_threadsafe_function prevent it from being destroyed. napi_acquire_threadsafe_function and napi_release_threadsafe_function are available for that purpose.

此 API 只能从主线程调用。

This API may only be called from the main thread.

napi_unref_threadsafe_function#

NAPI_EXTERN napi_status
napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func); 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [in] func:要取消引用的线程安全函数。

    [in] func: The thread-safe function to unreference.

该 API 用于指示在主线程上运行的事件循环可能会在 func 被销毁之前退出。与 uv_unref 类似,它也是幂等的。

This API is used to indicate that the event loop running on the main thread may exit before func is destroyed. Similar to uv_unref it is also idempotent.

此 API 只能从主线程调用。

This API may only be called from the main thread.

其他实用工具#

Miscellaneous utilities

node_api_get_module_file_name#

NAPI_EXTERN napi_status
node_api_get_module_file_name(napi_env env, const char** result);
 
  • [in] env:调用 API 的环境。

    [in] env: The environment that the API is invoked under.

  • [out] result:包含加载项加载位置的绝对路径的 URL。对于本地文件系统上的文件,它将以 file:// 开头。该字符串以 null 结尾并归 env 所有,因此不得修改或释放。

    [out] result: A URL containing the absolute path of the location from which the add-on was loaded. For a file on the local file system it will start with file://. The string is null-terminated and owned by env and must thus not be modified or freed.

如果加载项加载过程无法在加载期间建立加载项的文件名,则 result 可能是一个空字符串。

result may be an empty string if the add-on loading process fails to establish the add-on's file name during loading.