Spec-Zone.ru › Node.js 18 LTS

Node-API

Стабильность: 2 - Стабильная

Node-API (ранее N-API) — это API для создания нативных плагинов. Оно независимо от базового JavaScript-движка (например, V8) и поддерживается как часть самого Node.js. Это API гарантирует стабильность интерфейса бинарных данных (ABI) в разных версиях Node.js. Оно предназначено для изоляции плагинов от изменений в базовом JavaScript-движке и позволяет модулям, скомпилированным для одной основной версии, работать в более поздних основных версиях Node.js без перекомпиляции. Руководство по стабильности ABI предоставляет более подробное объяснение.

Плагины создаются/упаковываются с тем же подходом/инструментами, что и в разделе, озаглавленном Плагины на C++. Единственное отличие — набор API, используемый нативным кодом. Вместо использования API V8 или Native Abstractions for Node.js используются функции, доступные в Node-API.

API, предоставляемые Node-API, обычно используются для создания и манипулирования JavaScript-значениями. Концепции и операции, как правило, соответствуют идеям, указанным в спецификации языка ECMA-262. API имеют следующие свойства:

  • Все вызовы Node-API возвращают код состояния типа napi_status. Этот код состояния указывает, был ли вызов API успешным или неудачным.
  • Значение возврата API передается через параметр-результат.
  • Все JavaScript-значения абстрагируются за непрозрачным типом, называемым napi_value.
  • В случае кода состояния ошибки дополнительную информацию можно получить с помощью napi_get_last_error_info. Более подробную информацию можно найти в разделе обработки ошибок Обработка ошибок.

Node-API — это C API, гарантирующий стабильность ABI в разных версиях Node.js и уровнях компилятора. C++ API может быть проще в использовании. Для поддержки использования C++ проект содержит модуль обёртки на C++, называемый node-addon-api. Эта обёртка предоставляет интегрируемый C++ API. Бинарные файлы, созданные с помощью node-addon-api будут зависеть от символов функций Node-API на основе C, экспортируемых Node.js. node-addon-api — более эффективный способ написания кода, вызывающего Node-API. Например, следующий node-addon-api код. Первая секция демонстрирует node-addon-api код, а вторая — код, который фактически используется в плагине.

Object obj = Object::New(env);
obj["foo"] = String::New(env, "bar"); copy
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;
} copy

В результате плагин использует только экспортированные C API. В результате он все ещё получает преимущества стабильности ABI, предоставляемой C API.

При использовании node-addon-api вместо C API, начните с документации API docs для node-addon-api.

Ресурс Node-API Resource предоставляет отличное руководство и советы для разработчиков, только начинающих работать с Node-API и node-addon-api. Дополнительные медиа-ресурсы можно найти на странице Node-API Media.

Последствия стабильности ABI

Несмотря на то, что Node-API гарантирует стабильность ABI, другие части Node.js не гарантируют этого, и любые внешние библиотеки, используемые из плагина, тоже могут не гарантировать этого. В частности, ни один из следующих API не гарантирует стабильность ABI в разных основных версиях:

  • API Node.js на C++, доступные через любой из

    #include <node.h>
    #include <node_buffer.h>
    #include <node_version.h>
    #include <node_object_wrap.h> copy
  • API libuv, которые также включены в Node.js и доступны через

    #include <uv.h> copy
  • API V8, доступный через

    #include <v8.h> copy

Таким образом, для того, чтобы плагин оставался совместимым по ABI в основных версиях Node.js, он должен использовать исключительно Node-API, ограничивая себя использованием

#include <node_api.h> copy

и проверяя для всех внешних библиотек, которые он использует, что внешняя библиотека гарантирует стабильность ABI, аналогичную Node-API.

Компиляция

В отличие от модулей, написанных на JavaScript, разработка и развертывание нативных плагинов Node.js с использованием Node-API требует дополнительного набора инструментов. Помимо базовых инструментов, необходимых для разработки для Node.js, разработчик нативного плагина также нуждается в инструментарии, способном компилировать код C и C++ в бинарный файл. Кроме того, в зависимости от того, как развернут нативный плагин, пользователю нативного плагина также потребуется установленный инструментарий C/C++.

Для разработчиков Linux необходимые пакеты инструментария C/C++ легко доступны. GCC широко используется в сообществе Node.js для сборки и тестирования на различных платформах. Для многих разработчиков инфраструктура компилятора LLVM также является хорошим выбором.

Для разработчиков macOS Xcode предоставляет все необходимые инструменты компилятора. Однако нет необходимости устанавливать весь IDE Xcode. Следующая команда устанавливает необходимый инструментарий:

xcode-select --install copy

Для разработчиков Windows Visual Studio предоставляет все необходимые инструменты компилятора. Однако нет необходимости устанавливать весь IDE Visual Studio. Следующая команда устанавливает необходимый инструментарий:

npm install --global windows-build-tools copy

Ниже описаны дополнительные инструменты, доступные для разработки и развертывания нативных плагинов Node.js.

Инструменты сборки

Для успешной установки нативного плагина все перечисленные инструменты требуют, чтобы у пользователей нативного плагина был установлен инструментарий C/C++.

node-gyp

node-gyp — это система сборки, основанная на gyp-next, вилке Google's GYP, и входит в комплект npm. Для работы GYP, а значит и node-gyp, необходима установка Python.

Исторически node-gyp был инструментом выбора для сборки нативных плагинов. Он имеет широкое распространение и документацию. Однако некоторые разработчики сталкивались с ограничениями в node-gyp.

CMake.js

CMake.js — это альтернативная система сборки, основанная на CMake.

CMake.js — хороший выбор для проектов, которые уже используют CMake, или для разработчиков, столкнувшихся с ограничениями в node-gyp.

Загрузка предварительно скомпилированных бинарных файлов

Три перечисленных инструмента позволяют разработчикам и авторам нативных плагинов создавать и загружать бинарные файлы на публичные или частные сервера. Эти инструменты обычно интегрируются с системами CI/CD сборки, такими как Travis CI и AppVeyor, для сборки и загрузки бинарных файлов для различных платформ и архитектур. Затем эти бинарные файлы доступны для загрузки пользователям, которым не нужен установленный инструментарий C/C++.

node-pre-gyp

node-pre-gyp — инструмент, основанный на node-gyp, который добавляет возможность загрузки бинарных файлов на сервер по выбору разработчика. node-pre-gyp имеет особенно хорошую поддержку загрузки бинарных файлов в Amazon S3.

prebuild

prebuild — инструмент, который поддерживает сборку с помощью node-gyp или CMake.js. В отличие от node-pre-gyp, который поддерживает различные серверы, prebuild загружает бинарные файлы только в GitHub releases. prebuild — хороший выбор для GitHub-проектов, использующих CMake.js.

prebuildify

prebuildify — инструмент, основанный на node-gyp. Преимущество prebuildify заключается в том, что скомпилированные бинарные файлы включаются в нативный плагин при его загрузке в npm. Бинарные файлы скачиваются из npm и сразу же доступны пользователю модуля при установке нативного плагина.

Использование

Для использования функций Node-API включите файл node_api.h, который находится в каталоге src в дереве разработки node:

#include <node_api.h> copy

Это включит по умолчанию NAPI_VERSION для данной версии Node.js. Для обеспечения совместимости с определёнными версиями Node-API, версию можно указать явно при включении заголовка:

#define NAPI_VERSION 3
#include <node_api.h> copy

Это ограничивает поверхность Node-API только функциональностью, которая была доступна в указанных (и более ранних) версиях.

Некоторая часть поверхности Node-API является экспериментальной и требует явного включения:

#define NAPI_EXPERIMENTAL
#include <node_api.h> copy

В этом случае вся поверхность API, включая любые экспериментальные API, будет доступна коду модуля.

END_OF_DOCUMENT_MARKER

Матрица версий Node-API

Версии Node-API являются аддитивными и имеют отдельную версионирование от Node.js. Версия 4 является расширением версии 3, содержащей все API версии 3 с некоторыми дополнениями. Это означает, что перекомпиляция не требуется для новых версий Node.js, которые поддерживают более позднюю версию.

1 2 3
v6.x v6.14.2*
v8.x v8.6.0** v8.10.0* v8.11.2
v9.x v9.0.0* v9.3.0* v9.11.0*
≥ v10.x все выпуски все выпуски все выпуски
4 5 6 7 8
v10.x v10.16.0 v10.17.0 v10.20.0 v10.23.0
v11.x v11.8.0
v12.x v12.0.0 v12.11.0 v12.17.0 v12.19.0 v12.22.0
v13.x v13.0.0 v13.0.0
v14.x v14.0.0 v14.0.0 v14.0.0 v14.12.0 v14.17.0
v15.x v15.0.0 v15.0.0 v15.0.0 v15.0.0 v15.12.0
v16.x v16.0.0 v16.0.0 v16.0.0 v16.0.0 v16.0.0

* Node-API был экспериментальным.

** Node.js 8.0.0 включал Node-API в качестве экспериментального. Он был выпущен как Node-API версии 1, но продолжал развиваться до Node.js 8.6.0. API отличается в версиях до Node.js 8.6.0. Рекомендуется использовать Node-API версии 3 или новее.

Каждый документированный API Node-API будет иметь заголовок added in:, а стабильные API будут иметь дополнительный заголовок Node-API version:. API напрямую доступны при использовании версии Node.js, которая поддерживает версию Node-API, указанную в Node-API version: или выше. При использовании версии Node.js, которая не поддерживает указанную в Node-API version: версию, или если нет указанной Node-API version: версии, API будет доступен только в том случае, если #define NAPI_EXPERIMENTAL предшествует включению node_api.h или js_native_api.h. Если API, кажется, недоступен в версии Node.js, более поздней, чем указанная в added in:, это, скорее всего, причина отсутствия.

Node-API, связанные исключительно с доступом к функциям ECMAScript из нативного кода, можно найти отдельно в js_native_api.h и js_native_api_types.h. Определяемые в этих заголовках API включены в node_api.h и node_api_types.h. Заголовки структурированы таким образом, чтобы позволить реализации Node-API за пределами Node.js. Для таких реализаций API, специфичные для Node.js, могут быть неприменимы.

Части API, специфичные для Node.js, плагина могут быть отделены от кода, который экспонирует фактическую функциональность для среды JavaScript, чтобы последняя могла быть использована с несколькими реализациями Node-API. В примере ниже addon.c и addon.h относятся только к js_native_api.h. Это гарантирует, что addon.c можно повторно использовать для компиляции как с реализацией Node-API в Node.js, так и с любой реализацией Node-API за пределами Node.js.

addon_node.c — отдельный файл, содержащий специфичную для Node.js точку входа в плагин и инициализирующий плагин, вызывая addon.c, когда плагин загружается в среду Node.js.

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

#define NAPI_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 (!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;
  NAPI_CALL(env, napi_create_object(env, &result));

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

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

  return result;
} copy
// 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);
} copy

API жизненного цикла среды

Раздел 8.7 спецификации языка ECMAScript ECMAScript Language Specification определяет понятие «агент» как самодостаточную среду, в которой выполняется код JavaScript. Несколько таких агентов могут быть запущены и завершены процессом либо одновременно, либо последовательно.

Среда Node.js соответствует агенту ECMAScript. В основном процессе среда создается при запуске, а дополнительные среды могут быть созданы в отдельных потоках для работы в качестве потоков-рабочих нитей. При внедрении Node.js в другое приложение основной поток приложения также может многократно создавать и уничтожать среду Node.js в течение жизненного цикла процесса приложения, так что каждая созданная приложением среда Node.js может в свою очередь создавать и уничтожать дополнительные среды в качестве потоков-рабочих нитей.

С точки зрения нативного плагина это означает, что предоставляемые им связи могут вызываться многократно, из нескольких контекстов и даже одновременно из нескольких потоков.

Нативным плагинам может потребоваться выделение глобального состояния, которое они используют во время жизненного цикла среды Node.js, так чтобы состояние было уникальным для каждого экземпляра плагина.

Для этого Node-API предоставляет способ ассоциации данных таким образом, что его жизненный цикл связан с жизненным циклом среды Node.js.

napi_set_instance_data

Добавлен в: v12.8.0, v10.20.0 Версия N-API: 6
napi_status napi_set_instance_data(napi_env env,
                                   void* data,
                                   napi_finalize finalize_cb,
                                   void* finalize_hint); copy
  • [in] env: Среда, в которой вызывается вызов Node-API.
  • [in] data: Элемент данных, который нужно сделать доступным для связей этого экземпляра.
  • [in] finalize_cb: Функция, вызываемая при разборке среды. Функция получает data, чтобы освободить его. napi_finalize предоставляет дополнительные сведения.
  • [in] finalize_hint: Необязательный указатель, передаваемый в обратный вызов finalize при сборе.

Возвращает napi_ok в случае успешного выполнения API.

Этот API связывает data с текущей работающей средой Node.js. data может быть позже получен с помощью napi_get_instance_data(). Любые существующие данные, связанные с текущей работающей средой Node.js, которые были установлены с помощью предыдущего вызова napi_set_instance_data(), будут перезаписаны. Если finalize_cb предоставлялся предыдущим вызовом, он не будет вызван.

napi_get_instance_data

Добавлен в: v12.8.0, v10.20.0 Версия N-API: 6
napi_status napi_get_instance_data(napi_env env,
                                   void** data); copy
  • [in] env: Среда, в которой вызывается вызов Node-API.
  • [out] data: Элемент данных, который ранее был связан с текущей работающей средой Node.js вызовом napi_set_instance_data().

Возвращает napi_ok в случае успешного выполнения API.

Этот API получает данные, которые ранее были связаны с текущей работающей средой Node.js через napi_set_instance_data(). Если данные не установлены, вызов будет выполнен успешно, и data будет установлено в значение NULL.

Основные типы данных Node-API

Node-API предоставляет следующие фундаментальные типы данных в качестве абстракций, используемых различными API. Эти API следует рассматривать как непрозрачные, инспектируемые только с помощью других вызовов Node-API.

napi_status

Добавлен в: v8.0.0 Версия N-API: 1

Целочисленный код состояния, указывающий на успех или неудачу вызова Node-API. В настоящее время поддерживаются следующие коды состояния.

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; copy

Если требуется дополнительная информация при возвращении API неудачного состояния, её можно получить, вызвав napi_get_last_error_info.

napi_extended_error_info

Добавлен в: v8.0.0 Версия N-API: 1
typedef struct {
  const char* error_message;
  void* engine_reserved;
  uint32_t engine_error_code;
  napi_status error_code;
} napi_extended_error_info; copy
  • error_message: Строка UTF8, содержащая VM-нейтральное описание ошибки.
  • engine_reserved: Зарезервировано для VM-специфичных деталей ошибки. В настоящее время не реализовано ни для одного VM.
  • engine_error_code: VM-специфический код ошибки. В настоящее время не реализован ни для одного VM.
  • error_code: Код состояния Node-API, возникший в результате последней ошибки.

Дополнительную информацию см. в разделе Обработка ошибок.

napi_env

napi_env используется для представления контекста, который реализация Node-API может использовать для сохранения VM-специфического состояния. Эта структура передаётся в нативные функции при их вызове, и её необходимо передавать обратно при выполнении вызовов Node-API. В частности, та же napi_env, что была передана при первоначальном вызове нативной функции, должна быть передана при любых последующих вложенных вызовах Node-API. Кэширование napi_env в целях общего повторного использования, а также передача napi_env между экземплярами одного и того же плагина, работающего в разных потоках Worker, запрещено. napi_env становится недействительным при разгрузке экземпляра нативного плагина. Уведомление об этом событии осуществляется через обратные вызовы, предоставленные napi_add_env_cleanup_hook и napi_set_instance_data.

napi_value

Это непрозрачный указатель, используемый для представления значения JavaScript.

napi_threadsafe_function

Добавлен в: v10.6.0 Версия N-API: 4

Это непрозрачный указатель, представляющий функцию JavaScript, которую можно вызывать асинхронно из нескольких потоков через napi_call_threadsafe_function().

napi_threadsafe_function_release_mode

Добавлен в: v10.6.0 Версия N-API: 4

Значение, которое нужно предоставить napi_release_threadsafe_function() для указания, должна ли функция с защитой от потоков быть закрыта немедленно (napi_tsfn_abort) или просто освобождена (napi_tsfn_release) и, таким образом, доступна для последующего использования через napi_acquire_threadsafe_function() и napi_call_threadsafe_function().

typedef enum {
  napi_tsfn_release,
  napi_tsfn_abort
} napi_threadsafe_function_release_mode; copy

napi_threadsafe_function_call_mode

Добавлен в: v10.6.0 Версия N-API: 4

Значение, которое нужно предоставить napi_call_threadsafe_function() для указания, следует ли блокировать вызов, когда очередь, связанная с функцией с защитой от потоков, заполнена.

typedef enum {
  napi_tsfn_nonblocking,
  napi_tsfn_blocking
} napi_threadsafe_function_call_mode; copy

Типы управления памятью Node-API

napi_handle_scope

Это абстракция, используемая для управления и изменения срока жизни объектов, созданных в определённом пространстве имён. В общем случае, значения Node-API создаются в контексте области видимости handle. Когда нативная функция вызывается из JavaScript, существует область видимости handle по умолчанию. Если пользователь явно не создаёт новую область видимости handle, значения Node-API будут созданы в области видимости handle по умолчанию. Для любых вызовов кода за пределами выполнения нативной функции (например, во время вызова обратного вызова libuv), модуль должен создать область видимости перед вызовом любых функций, которые могут привести к созданию значений JavaScript.

Области видимости handle создаются с помощью napi_open_handle_scope и уничтожаются с помощью napi_close_handle_scope. Закрытие области видимости может указать сборщику мусора, что все napi_value созданные в течение срока жизни области видимости handle больше не ссылаются из текущей области видимости.

Для получения дополнительной информации см. раздел Управление сроком жизни объектов.

napi_escapable_handle_scope
Добавлен в: v8.0.0 Версия N-API: 1

Управляемые области видимости handle — это особый тип области видимости handle для возврата значений, созданных в определённой области видимости handle, в родительскую область видимости.

napi_ref
Добавлен в: v8.0.0 Версия N-API: 1

Это абстракция, используемая для ссылки на napi_value. Это позволяет пользователям управлять сроком жизни значений JavaScript, включая явное определение их минимального срока жизни.

Для получения дополнительной информации см. раздел Управление сроком жизни объектов.

napi_type_tag
Добавлен в: v14.8.0, v12.19.0 Версия N-API: 8

Значение из 128 бит, хранящееся как два беззнаковых 64-битных целых числа. Оно служит UUID, с помощью которого объекты JavaScript или externals могут быть «мечены» для обеспечения принадлежности к определённому типу. Это более строгая проверка, чем napi_instanceof, потому что последняя может давать ложноположительные результаты, если прототип объекта был изменён. Разметка типа наиболее полезна в сочетании с napi_wrap, поскольку она гарантирует, что указатель, полученный от обернутого объекта, можно безопасно привести к нативному типу, соответствующему тегу типа, который был ранее применён к объекту JavaScript.

typedef struct {
  uint64_t lower;
  uint64_t upper;
} napi_type_tag; copy
napi_async_cleanup_hook_handle
Добавлен в: v14.10.0, v12.19.0

Непрозрачное значение, возвращаемое napi_add_async_cleanup_hook. Его необходимо передать в napi_remove_async_cleanup_hook, когда цепочка асинхронных событий очистки завершается.

Типы обратных вызовов Node-API

napi_callback_info
Добавлен в: v8.0.0 Версия N-API: 1

Непрозрамый тип данных, передаваемый функции обратного вызова. Он может использоваться для получения дополнительной информации о контексте, в котором был вызван обратный вызов.

napi_callback
Добавлен в: v8.0.0 Версия N-API: 1

Тип указателя на функцию для пользовательских нативных функций, которые должны быть экспонированы для JavaScript через Node-API. Функции обратного вызова должны удовлетворять следующей сигнатуре:

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

Если создание области видимости handle и/или обратного вызова внутри napi_callback не требуется по причинам, описанным в разделе Управление сроком жизни объекта.

napi_finalize
Добавлен в: v8.0.0 Версия N-API: 1

Тип указателя на функцию, предоставляемую плагином, которая позволяет пользователю получать уведомления, когда данные, принадлежащие внешним источникам, готовы к очистке, потому что объект, с которым они были связаны, был собран сборщиком мусора. Пользователь должен предоставить функцию, удовлетворяющую следующей сигнатуре, которая будет вызвана при сборе объекта. В настоящее время napi_finalize можно использовать для определения момента, когда собираются объекты, имеющие внешние данные.

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

Если создание области видимости handle и/или обратного вызова внутри тела функции не требуется по причинам, описанным в разделе Управление сроком жизни объекта.

Поскольку эти функции могут вызываться, когда движок JavaScript находится в состоянии, в котором он не может выполнять код JavaScript, некоторые вызовы Node-API могут возвращать napi_pending_exception даже в случае отсутствия ожидаемых исключений.

В случае node_api_create_external_string_latin1 и node_api_create_external_string_utf16 параметр env может быть null, поскольку внешние строки могут быть собраны на позднем этапе завершения среды.

История изменений:

  • экспериментальный (NAPI_EXPERIMENTAL определено):

    Вызовы Node-API, сделанные из finalizer, вернут napi_cannot_run_js при невозможности выполнения JavaScript движком JavaScript, а napi_exception_pending — при наличии ожидаемого исключения.

napi_async_execute_callback
Добавлен в: v8.0.0 Версия N-API: 1

Указатель на функцию, используемый с функциями, поддерживающими асинхронные операции. Функции обратного вызова должны удовлетворять следующей сигнатуре:

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

Реализации этой функции должны избегать выполнения вызовов Node-API, выполняющих JavaScript или взаимодействующих с объектами JavaScript. Вызовы Node-API должны быть в napi_async_complete_callback вместо. Не используйте параметр napi_env, так как это, скорее всего, приведёт к выполнению JavaScript.

napi_async_complete_callback
Добавлен в: v8.0.0 Версия N-API: 1

Указатель на функцию, используемый с функциями, поддерживающими асинхронные операции. Функции обратного вызова должны удовлетворять следующей сигнатуре:

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

Если создание области видимости handle и/или обратного вызова внутри тела функции не требуется по причинам, описанным в разделе Управление сроком жизни объекта.

napi_threadsafe_function_call_js
Добавлен в: v10.6.0 Версия N-API: 4

Указатель на функцию, используемый с асинхронными вызовами функций с защитой от потоков. Обратный вызов будет вызван в главном потоке. Его цель — использовать элемент данных, поступающий через очередь из одного из вторичных потоков, для построения параметров, необходимых для вызова JavaScript, обычно через napi_call_function, а затем выполнить вызов JavaScript.

Данные, поступающие из вторичного потока через очередь, предоставляются в параметре data, а функция JavaScript, которую нужно вызвать, — в параметре js_callback.

Node-API настраивает среду до вызова этого обратного вызова, поэтому достаточно вызвать функцию JavaScript через napi_call_function, а не через napi_make_callback.

Функции обратного вызова должны удовлетворять следующей сигнатуре:

typedef void (*napi_threadsafe_function_call_js)(napi_env env,
                                                 napi_value js_callback,
                                                 void* context,
                                                 void* data); copy
  • [in] env: Окружение для вызовов API, или NULL, если функция с защитой от потоков разрушается и data может потребоваться освободить.
  • [in] js_callback: Функция JavaScript для вызова, или NULL, если функция с защитой от потоков разрушается и data может потребоваться освободить. Также может быть NULL, если функция с защитой от потоков была создана без js_callback.
  • [in] context: Дополнительные данные, с которыми была создана функция с защитой от потоков.
  • [in] data: Данные, созданные вторичным потоком. Ответственность обратного вызова — преобразовать эти данные в значения JavaScript (с функциями Node-API), которые можно передавать в качестве параметров при вызове js_callback. Этот указатель полностью управляется потоками и этим обратным вызовом. Поэтому этот обратный вызов должен освободить данные.

Если нет причин, обсуждаемых в Управлении жизненным циклом объектов, создание дескриптора и/или области обратного вызова внутри тела функции не требуется.

napi_cleanup_hook
Добавлена в: v18.13.0 Версия N-API: 3

Указатель функции, используемый с napi_add_env_cleanup_hook. Он вызывается при разрушении среды.

Функции обратного вызова должны удовлетворять следующей сигнатуре:

typedef void (*napi_cleanup_hook)(void* data); copy
  • [in] data: Данные, переданные napi_add_env_cleanup_hook.
napi_async_cleanup_hook
Добавлена в: v14.10.0, v12.19.0

Указатель функции, используемый с napi_add_async_cleanup_hook. Он вызывается при разрушении среды.

Функции обратного вызова должны удовлетворять следующей сигнатуре:

typedef void (*napi_async_cleanup_hook)(napi_async_cleanup_hook_handle handle,
                                        void* data); copy
  • [in] handle: Дескриптор, который необходимо передать в napi_remove_async_cleanup_hook после завершения асинхронной очистки.
  • [in] data: Данные, переданные в napi_add_async_cleanup_hook.

Тело функции должно инициировать асинхронные действия по очистке, по завершении которых handle необходимо передать в вызове napi_remove_async_cleanup_hook.

Обработка ошибок

Node-API использует как возвращаемые значения, так и исключения JavaScript для обработки ошибок. В следующих разделах объясняется подход для каждого случая.

Возвращаемые значения

Все функции Node-API используют одинаковый шаблон обработки ошибок. Тип возвращаемого значения всех функций API — napi_status.

Возвращаемое значение будет napi_ok, если запрос был выполнен успешно и не было брошено неуловленное исключение JavaScript. Если произошла ошибка И было брошено исключение, будет возвращено значение napi_status для ошибки. Если было брошено исключение, но ошибка не произошла, будет возвращено napi_pending_exception.

В случаях, когда возвращается значение, отличное от napi_ok или napi_pending_exception, необходимо вызвать napi_is_exception_pending, чтобы проверить, ожидается ли исключение. Подробности см. в разделе об исключениях.

Полный набор возможных значений napi_status определен в napi_api_types.h.

Возвращаемое значение napi_status предоставляет независимое от виртуальной машины представление произошедшей ошибки. В некоторых случаях полезно получить более подробную информацию, включая строку, представляющую ошибку, а также информацию, специфичную для виртуальной машины (движка).

Для получения этой информации предоставляется napi_get_last_error_info, который возвращает структуру napi_extended_error_info. Формат структуры napi_extended_error_info следующий:

Добавлен в: v8.0.0 Версия N-API: 1
typedef struct napi_extended_error_info {
  const char* error_message;
  void* engine_reserved;
  uint32_t engine_error_code;
  napi_status error_code;
}; copy
  • error_message: Текстовое представление произошедшей ошибки.
  • engine_reserved: Непрозрачная ручка, предназначенная только для использования движком.
  • engine_error_code: Код ошибки, специфичный для виртуальной машины.
  • error_code: Код состояния Node-API для последней ошибки.

napi_get_last_error_info возвращает информацию о последнем вызове функции Node-API.

Не полагайтесь на содержание или формат расширенной информации, так как она не подчиняется SemVer и может измениться в любое время. Она предназначена только для целей ведения журнала.

napi_get_last_error_info
Добавлен в: v8.0.0 Версия N-API: 1
napi_status
napi_get_last_error_info(napi_env env,
                         const napi_extended_error_info** result); copy
  • [in] env: Среда, в которой вызывается API.
  • [out] result: Структура napi_extended_error_info, содержащая дополнительную информацию об ошибке.

Возвращает napi_ok, если API выполнилось успешно.

Этот API получает структуру napi_extended_error_info с информацией о последней возникшей ошибке.

Содержимое возвращаемой структуры napi_extended_error_info действительно только до тех пор, пока функция Node-API не будет вызвана с той же env. Это включает в себя вызов napi_is_exception_pending, поэтому часто необходимо создать копию информации для ее последующего использования. Указатель, возвращаемый в error_message, указывает на статически определенную строку, поэтому его можно безопасно использовать, если вы скопировали его из поля error_message (которое будет перезаписано) до вызова другой функции Node-API.

Не полагайтесь на содержание или формат расширенной информации, так как она не подчиняется SemVer и может измениться в любое время. Она предназначена только для целей ведения журнала.

Этот API можно вызывать, даже если ожидается исключение JavaScript.

Исключения

Любой вызов функции Node-API может привести к ожидаемому исключению JavaScript. Это относится ко всем функциям API, даже к тем, которые могут не вызвать выполнение JavaScript.

Если возвращаемое значение napi_status функции равно napi_ok, значит, исключение не ожидается, и дополнительных действий не требуется. Если возвращаемое значение napi_status отличается от napi_ok или napi_pending_exception, для попытки восстановления и продолжения вместо простого немедленного возврата необходимо вызвать napi_is_exception_pending, чтобы определить, ожидается ли исключение.

Во многих случаях, когда функция Node-API вызывается, а исключение уже ожидается, функция вернётся немедленно с napi_status значением napi_pending_exception. Однако это не относится ко всем функциям. Node-API позволяет вызывать подмножество функций для выполнения некоторой минимальной очистки перед возвратом в JavaScript. В этом случае napi_status отразит статус для функции. Она не будет отражать предыдущие ожидающие исключения. Для избежания путаницы проверяйте статус ошибки после каждого вызова функции.

Когда ожидается исключение, можно использовать один из двух подходов.

Первый подход заключается в выполнении необходимой очистки и затем возврате, чтобы управление вернулось к JavaScript. В рамках перехода обратно в JavaScript исключение будет брошено в точке кода JavaScript, где вызывался родной метод. Поведение большинства вызовов Node-API не определено, пока ожидается исключение, и многие просто вернут napi_pending_exception, поэтому делайте как можно меньше действий и возвращайтесь в JavaScript, где исключение может быть обработано.

Второй подход заключается в попытке обработать исключение. Будут случаи, когда родной код может перехватить исключение, выполнить соответствующие действия и затем продолжить. Это рекомендуется только в особых случаях, когда известно, что исключение можно безопасно обработать. В этих случаях можно использовать napi_get_and_clear_last_exception для получения и очистки исключения. При успехе результат будет содержать дескриптор последнего брошенного JavaScript Object исключения. Если после получения исключения будет определено, что исключение всё же не может быть обработано, его можно повторно бросить с помощью napi_throw, где error — значение JavaScript, которое необходимо бросить.

Следующие вспомогательные функции также доступны в случае необходимости бросить исключение в родном коде или определить, является ли napi_value экземпляром объекта JavaScript Error: napi_throw_error, napi_throw_type_error, napi_throw_range_error, node_api_throw_syntax_error и napi_is_error.

Следующие вспомогательные функции также доступны в случае необходимости создания объекта Error: napi_create_error, napi_create_type_error, napi_create_range_error и node_api_create_syntax_error, где result — napi_value, который ссылается на новый созданный объект JavaScript Error.

Проект Node.js добавляет коды ошибок ко всем ошибкам, генерируемым внутри. Цель состоит в том, чтобы приложения использовали эти коды ошибок для проверки на ошибки. Соответствующие сообщения об ошибках останутся, но будут использоваться только для ведения журнала и отображения с ожиданием того, что сообщение может измениться без применения SemVer. Для поддержки этой модели в Node-API, как во внутренней функциональности, так и в функциональности модулей (так как это хорошая практика), функции throw_ и create_ принимают необязательный параметр code, который представляет собой строку для добавления кода в объект ошибки. Если необязательный параметр NULL, код к ошибке не будет добавлен. Если код предоставлен, имя, связанное с ошибкой, также обновляется:

originalName [code] copy

где originalName — исходное имя, связанное с ошибкой, а code — предоставленный код. Например, если код — 'ERR_ERROR_1', и создаётся TypeError, имя будет:

TypeError [ERR_ERROR_1] copy
napi_throw
Добавлен в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] error: Значение JavaScript, которое необходимо бросить.

Возвращает napi_ok, если API выполнилось успешно.

Этот API бросает предоставленное значение JavaScript.

napi_throw_error
Добавлен в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_throw_error(napi_env env,
                                         const char* code,
                                         const char* msg); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] code: Необязательный код ошибки, который нужно установить для ошибки.
  • [in] msg: Строка C, представляющая текст, который нужно связать с ошибкой.

Возвращает napi_ok, если API выполнилось успешно.

Этот API бросает JavaScript Error с предоставленным текстом.

napi_throw_type_error
Добавлен в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_throw_type_error(napi_env env,
                                              const char* code,
                                              const char* msg); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] code: Необязательный код ошибки, который нужно установить для ошибки.
  • [in] msg: Строка C, представляющая текст, который нужно связать с ошибкой.

Возвращает napi_ok, если API выполнилось успешно.

Этот API бросает JavaScript TypeError с предоставленным текстом.

napi_throw_range_error
Добавлен в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_throw_range_error(napi_env env,
                                               const char* code,
                                               const char* msg); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] code: Необязательный код ошибки, который нужно установить для ошибки.
  • [in] msg: Строка C, представляющая текст, который нужно связать с ошибкой.

Возвращает napi_ok, если API выполнилось успешно.

Этот API бросает JavaScript RangeError с предоставленным текстом.

node_api_throw_syntax_error
Добавлен в: v17.2.0, v16.14.0 Версия N-API: 9
NAPI_EXTERN napi_status node_api_throw_syntax_error(napi_env env,
                                                    const char* code,
                                                    const char* msg); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] code: Необязательный код ошибки, который нужно установить для ошибки.
  • [in] msg: Строка C, представляющая текст, который нужно связать с ошибкой.

Возвращает napi_ok, если API выполнилось успешно.

Этот API бросает JavaScript SyntaxError с предоставленным текстом.

napi_is_error
Добавлен в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_is_error(napi_env env,
                                      napi_value value,
                                      bool* result); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: napi_value для проверки.
  • [out] result: Булево значение, устанавливаемое в true, если napi_value представляет ошибку, и в false в противном случае.

Возвращает napi_ok при успешном выполнении API.

Этот API запрашивает napi_value для проверки, является ли он объектом ошибки.

napi_create_error
Добавлена в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_create_error(napi_env env,
                                          napi_value code,
                                          napi_value msg,
                                          napi_value* result); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] code: Необязательный napi_value со строкой для кода ошибки, который будет связан с ошибкой.
  • [in] msg: napi_value , ссылающийся на JavaScript string , используемый в качестве сообщения для Error.
  • [out] result: napi_value , представляющий созданную ошибку.

Возвращает napi_ok при успешном выполнении API.

Этот API возвращает JavaScript Error с предоставленным текстом.

napi_create_type_error
Добавлена в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_create_type_error(napi_env env,
                                               napi_value code,
                                               napi_value msg,
                                               napi_value* result); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] code: Необязательный napi_value со строкой для кода ошибки, который будет связан с ошибкой.
  • [in] msg: napi_value , ссылающийся на JavaScript string , используемый в качестве сообщения для Error.
  • [out] result: napi_value , представляющий созданную ошибку.

Возвращает napi_ok при успешном выполнении API.

Этот API возвращает JavaScript TypeError с предоставленным текстом.

napi_create_range_error
Добавлена в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_create_range_error(napi_env env,
                                                napi_value code,
                                                napi_value msg,
                                                napi_value* result); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] code: Необязательный napi_value со строкой для кода ошибки, который будет связан с ошибкой.
  • [in] msg: napi_value , ссылающийся на JavaScript string , используемый в качестве сообщения для Error.
  • [out] result: napi_value , представляющий созданную ошибку.

Возвращает napi_ok при успешном выполнении API.

Этот API возвращает JavaScript RangeError с предоставленным текстом.

node_api_create_syntax_error
Добавлена в: v17.2.0, v16.14.0 Версия N-API: 9
NAPI_EXTERN napi_status node_api_create_syntax_error(napi_env env,
                                                     napi_value code,
                                                     napi_value msg,
                                                     napi_value* result); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] code: Необязательный napi_value со строкой для кода ошибки, который будет связан с ошибкой.
  • [in] msg: napi_value , ссылающийся на JavaScript string , используемый в качестве сообщения для Error.
  • [out] result: napi_value , представляющий созданную ошибку.

Возвращает napi_ok при успешном выполнении API.

Этот API возвращает JavaScript SyntaxError с предоставленным текстом.

napi_get_and_clear_last_exception
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_and_clear_last_exception(napi_env env,
                                              napi_value* result); copy
  • [in] env: Окружение, в котором вызывается API.
  • [out] result: Исключение, если оно ожидается, NULL в противном случае.

Возвращает napi_ok при успешном выполнении API.

Этот API можно вызывать, даже если ожидается JavaScript-исключение.

napi_is_exception_pending
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_is_exception_pending(napi_env env, bool* result); copy
  • [in] env: Окружение, в котором вызывается API.
  • [out] result: Булево значение, устанавливаемое в true, если ожидается исключение.

Возвращает napi_ok при успешном выполнении API.

Этот API можно вызывать, даже если ожидается JavaScript-исключение.

napi_fatal_exception
Добавлена в: v9.10.0 Версия N-API: 3
napi_status napi_fatal_exception(napi_env env, napi_value err); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] err: Ошибка, которая передается в 'uncaughtException'.

Вызвать 'uncaughtException' в JavaScript. Полезно, если асинхронный обратный вызов выбрасывает исключение без возможности восстановления.

Fatal errors

В случае неисправимой ошибки в нативном дополнении, может быть выброшена фатальная ошибка, чтобы немедленно завершить процесс.

napi_fatal_error
Добавлена в: v8.2.0 Версия N-API: 1
NAPI_NO_RETURN void napi_fatal_error(const char* location,
                                     size_t location_len,
                                     const char* message,
                                     size_t message_len); copy
  • [in] location: Необязательное место, где произошла ошибка.
  • [in] location_len: Длина места в байтах, или NAPI_AUTO_LENGTH если оно завершается нулём.
  • [in] message: Сообщение, связанное с ошибкой.
  • [in] message_len: Длина сообщения в байтах, или NAPI_AUTO_LENGTH если оно завершается нулём.

Функция не возвращает значение, процесс будет завершен.

Этот API можно вызывать, даже если ожидается JavaScript-исключение.

Управление жизненным циклом объектов

При выполнении вызовов Node-API могут возвращаться дескрипторы объектов из кучи для подлежащей виртуальной машины в виде napi_values. Эти дескрипторы должны удерживать объекты «живыми» до тех пор, пока они больше не требуются нативному коду, иначе объекты могут быть собраны сборщиком мусора до завершения использования их нативным кодом.

Когда возвращаются дескрипторы объектов, они связываются с «областью видимости». Срок жизни по умолчанию связан со сроком жизни вызова нативного метода. В результате по умолчанию дескрипторы остаются валидными, а связанные с ними объекты остаются живыми на протяжении всего времени выполнения нативного метода.

Однако во многих случаях необходимо, чтобы дескрипторы оставались валидными либо короче, либо дольше, чем срок жизни нативного метода. В следующих разделах описаны функции Node-API, которые можно использовать для изменения срока жизни дескрипторов от значения по умолчанию.

Сокращение срока жизни дескрипторов по сравнению со сроком жизни нативного метода

Часто необходимо уменьшить срок жизни дескрипторов по сравнению со сроком жизни нативного метода. Например, рассмотрим нативный метод, у которого есть цикл, перебирающий элементы в большом массиве:

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
} copy

Это приведет к созданию большого количества дескрипторов, что потребует значительных ресурсов. Кроме того, даже если нативный код может использовать только последний дескриптор, все связанные объекты также будут поддерживаться живыми, так как они все находятся в одной и той же области видимости.

Для решения этой проблемы Node-API предоставляет возможность создания новой «области видимости», к которой будут привязаны вновь созданные дескрипторы. После того, как эти дескрипторы больше не нужны, область видимости может быть «закрыта», и все дескрипторы, связанные с этой областью, станут невалидными. Доступные методы для открытия/закрытия областей видимости — napi_open_handle_scope и napi_close_handle_scope.

Node-API поддерживает только одну вложенную иерархию областей видимости. В любой момент времени активна только одна область видимости, и все новые дескрипторы будут связаны с этой областью, пока она активна. Области видимости должны закрываться в обратном порядке, в котором они открываются. Кроме того, все области видимости, созданные внутри нативного метода, должны быть закрыты перед возвратом из этого метода.

На примере выше, добавление вызовов napi_open_handle_scope и napi_close_handle_scope гарантирует, что в течение всего выполнения цикла будет валиден только один дескриптор:

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;
  }
} copy

При вложенности областей видимости существуют случаи, когда дескриптор из внутренней области видимости должен существовать дольше, чем сама область. Node-API поддерживает «область видимости с возможностью выхода за пределы» для решения этой проблемы. Область видимости с возможностью выхода за пределы позволяет продвинуть один дескриптор так, чтобы он «вышел за пределы» текущей области видимости, и срок жизни дескриптора изменится с текущей области на область внешнего уровня.

Доступные методы для открытия/закрытия областей видимости с возможностью выхода за пределы — napi_open_escapable_handle_scope и napi_close_escapable_handle_scope.

Запрос на продвижение дескриптора выполняется с помощью napi_escape_handle, который может быть вызван только один раз.

napi_open_handle_scope
Добавлена в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_open_handle_scope(napi_env env,
                                               napi_handle_scope* result); copy
  • [in] env: Среда, в которой вызывается API.
  • [out] result: napi_value представляющий новую область видимости.

Возвращает napi_ok в случае успешного выполнения API.

Этот API открывает новую область видимости.

napi_close_handle_scope
Добавлена в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_close_handle_scope(napi_env env,
                                                napi_handle_scope scope); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] scope: napi_value представляющий область видимости, которую нужно закрыть.

Возвращает napi_ok в случае успешного выполнения API.

Этот API закрывает переданную область видимости. Области видимости должны закрываться в обратном порядке, в котором они были созданы.

Этот API может быть вызван даже при наличии ожидающего JavaScript исключения.

napi_open_escapable_handle_scope
Добавлена в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status
    napi_open_escapable_handle_scope(napi_env env,
                                     napi_handle_scope* result); copy
  • [in] env: Среда, в которой вызывается API.
  • [out] result: napi_value представляющий новую область видимости.

Возвращает napi_ok в случае успешного выполнения API.

Этот API открывает новую область видимости, из которой один объект может быть перемещен во внешнюю область видимости.

napi_close_escapable_handle_scope
Добавлена в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status
    napi_close_escapable_handle_scope(napi_env env,
                                      napi_handle_scope scope); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] scope: napi_value представляющий область видимости, которую нужно закрыть.

Возвращает napi_ok в случае успешного выполнения API.

Этот API закрывает переданную область видимости. Области видимости должны закрываться в обратном порядке, в котором они были созданы.

Этот API может быть вызван даже при наличии ожидающего JavaScript исключения.

napi_escape_handle
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_escape_handle(napi_env env,
                               napi_escapable_handle_scope scope,
                               napi_value escapee,
                               napi_value* result); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] scope: napi_value представляющий текущую область видимости.
  • [in] escapee: napi_value представляющий JavaScript Object для выхода за пределы.
  • [out] result: napi_value представляющий дескриптор объекта, вышедшего за пределы, во внешней области видимости.

Возвращает napi_ok в случае успешного выполнения API.

Этот API продвигает дескриптор к объекту JavaScript, чтобы он был валиден на протяжении всего срока жизни внешней области видимости. Он может быть вызван только один раз на область видимости. Если он вызывается более одного раза, будет возвращено сообщение об ошибке.

Этот API может быть вызван даже при наличии ожидающего JavaScript исключения.

Ссылки на значения со сроком жизни, превышающим срок жизни нативного метода

В некоторых случаях дополнению потребуется возможность создавать и ссылаться на значения со сроком жизни, превышающим срок действия одного вызова нативного метода. Например, для создания конструктора и последующего использования этого конструктора в запросе на создание экземпляров необходимо иметь возможность ссылаться на объект конструктора в различных запросах создания экземпляров. Это невозможно сделать с обычным дескриптором, возвращаемым как napi_value, как описано в предыдущем разделе. Срок жизни обычного дескриптора управляется областями видимости, и все области видимости должны быть закрыты перед завершением нативного метода.

Node-API предоставляет методы для создания постоянных ссылок на значения. В настоящее время Node-API позволяет создавать ссылки только для ограниченного набора типов значений, включая объект, внешний, функцию и символ.

У каждой ссылки есть связанный счетчик со значением 0 или выше, который определяет, будет ли ссылка удерживать соответствующее значение живым. Ссылки со значением счетчика 0 не препятствуют сборке мусора для значений. Значения типов object (объект, функция, внешний) и symbol становятся «слабыми» ссылками и по-прежнему могут быть доступны, пока они не собраны сборщиком мусора. Любой счетчик, больший 0, предотвратит сборку мусора для значений.

Значения типа symbol имеют различные варианты. Истинное поведение слабой ссылки поддерживается только локальными символами, созданными с помощью функции napi_create_symbol или вызовов конструкторов JavaScript Symbol(). Глобально зарегистрированные символы, созданные с помощью функции node_api_symbol_for или вызовов функций JavaScript Symbol.for(), всегда являются сильными ссылками, поскольку сборщик мусора не собирает их. То же самое относится к хорошо известным символам, таким как Symbol.iterator. Они также никогда не собираются сборщиком мусора.

Ссылки могут быть созданы с начальным значением счетчика. Затем счетчик можно изменить с помощью napi_reference_ref и napi_reference_unref. Если объект собирается сборщиком мусора, а значение счетчика ссылки равно 0, все последующие вызовы получения значения объекта, связанного с ссылкой napi_get_reference_value, вернут NULL для возвращаемого napi_value. Попытка вызвать napi_reference_ref для ссылки, объект которой был собран, приведет к ошибке.

Ссылки должны быть удалены, когда они больше не нужны дополнению. При удалении ссылки она больше не будет препятствовать сбору мусора для соответствующего объекта. Отсутствие удаления постоянной ссылки приводит к «утечке памяти», при которой как нативная память для постоянной ссылки, так и соответствующий объект в куче сохраняются навсегда.

Может быть создано несколько постоянных ссылок, которые ссылаются на один и тот же объект, каждая из которых либо удерживает объект живым, либо нет, в зависимости от собственного счетчика. Несколько постоянных ссылок на один и тот же объект могут привести к неожиданному сохранению живой нативной памяти. Нативные структуры для постоянной ссылки должны быть сохранены до тех пор, пока не будут выполнены финализаторы для объекта, на который ссылаются. Если создается новая постоянная ссылка на тот же объект, финализаторы этого объекта не будут выполнены, и нативная память, указанная первой постоянной ссылкой, не будет освобождена. Это можно избежать, вызвав napi_delete_reference в дополнение к napi_reference_unref, когда это возможно.

История изменений:

  • Экспериментальный (NAPI_EXPERIMENTAL определен):

    Ссылки могут быть созданы для всех типов значений. Новые поддерживаемые типы значений не поддерживают семантику слабой ссылки, и значения этих типов освобождаются, когда счетчик ссылок становится 0, и больше не могут быть доступны по ссылке.

napi_create_reference
Добавлена в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_create_reference(napi_env env,
                                              napi_value value,
                                              uint32_t initial_refcount,
                                              napi_ref* result); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: napi_value для которого создается ссылка.
  • [in] initial_refcount: Начальный счетчик ссылок для новой ссылки.
  • [out] result: napi_ref указывающий на новую ссылку.

Возвращает napi_ok в случае успешного выполнения API.

Этот API создает новую ссылку с указанным счетчиком ссылок на значение, переданное в качестве аргумента.

napi_delete_reference
Добавлена в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] ref: napi_ref для удаления.

Возвращает napi_ok в случае успешного выполнения API.

Данный API удаляет переданную ссылку.

Этот API может быть вызван даже при наличии ожидающейся JavaScript-исключения.

napi_reference_ref
Добавлен в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_reference_ref(napi_env env,
                                           napi_ref ref,
                                           uint32_t* result); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] ref: napi_ref для которого необходимо увеличить счётчик ссылок.
  • [out] result: Новый счётчик ссылок.

Возвращает napi_ok в случае успешного выполнения API.

Этот API увеличивает счётчик ссылок для переданной ссылки и возвращает результирующий счётчик ссылок.

napi_reference_unref
Добавлен в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_reference_unref(napi_env env,
                                             napi_ref ref,
                                             uint32_t* result); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] ref: napi_ref для которого необходимо уменьшить счётчик ссылок.
  • [out] result: Новый счётчик ссылок.

Возвращает napi_ok в случае успешного выполнения API.

Этот API уменьшает счётчик ссылок для переданной ссылки и возвращает результирующий счётчик ссылок.

napi_get_reference_value
Добавлен в: v8.0.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_get_reference_value(napi_env env,
                                                 napi_ref ref,
                                                 napi_value* result); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] ref: napi_ref для которого запрашивается соответствующее значение.
  • [out] result: napi_value , на который ссылается napi_ref.

Возвращает napi_ok в случае успешного выполнения API.

Если ссылка всё ещё действительна, этот API возвращает napi_value , представляющее JavaScript-значение, связанное с napi_ref. В противном случае, результат будет NULL.

Очистка при выходе из текущей среды Node.js

Хотя процесс Node.js обычно освобождает все свои ресурсы при выходе, встраивающие Node.js, или будущая поддержка рабочих потоков, могут потребовать от дополнений зарегистрировать обработчики очистки, которые будут выполнены после выхода текущей среды Node.js.

Node-API предоставляет функции для регистрации и отмены регистрации таких обратных вызовов. При выполнении этих обратных вызовов все ресурсы, удерживаемые дополнением, должны быть освобождены.

napi_add_env_cleanup_hook
Добавлен в: v10.2.0 Версия N-API: 3
NODE_EXTERN napi_status napi_add_env_cleanup_hook(napi_env env,
                                                  napi_cleanup_hook fun,
                                                  void* arg); copy

Регистрирует fun в качестве функции, которая будет выполнена с параметром arg после выхода текущей среды Node.js.

Функцию можно безопасно указать несколько раз с различными значениями arg. В этом случае она будет вызвана несколько раз. Указание одних и тех же значений fun и arg несколько раз запрещено и приведёт к аварийному завершению процесса.

Обработчики будут вызваны в обратном порядке, т.е. последний добавленный будет вызван первым.

Удаление этого обработчика можно выполнить с помощью napi_remove_env_cleanup_hook. Как правило, это происходит при разборке ресурса, для которого был добавлен этот обработчик.

Для асинхронной очистки доступен napi_add_async_cleanup_hook.

napi_remove_env_cleanup_hook
Добавлен в: v10.2.0 Версия N-API: 3
NAPI_EXTERN napi_status napi_remove_env_cleanup_hook(napi_env env,
                                                     void (*fun)(void* arg),
                                                     void* arg); copy

Отменяет регистрацию fun в качестве функции, которая будет выполнена с параметром arg при выходе текущей среды Node.js. И аргумент, и значение функции должны точно совпадать.

Функция должна была быть первоначально зарегистрирована с помощью napi_add_env_cleanup_hook, в противном случае процесс завершится аварийно.

napi_add_async_cleanup_hook
История
Версия Изменения
v14.10.0, v12.19.0

Изменена сигнатура обратного вызова hook.

v14.8.0, v12.19.0

Добавлен в: v14.8.0, v12.19.0

Версия N-API: 8
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); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] hook: Указатель на функцию, которая будет вызвана при завершении среды.
  • [in] arg: Указатель, который передаётся hook при вызове.
  • [out] remove_handle: Необязательная ручка, которая ссылается на асинхронный обработчик очистки.

Регистрирует hook, которая является функцией типа napi_async_cleanup_hook, как функцию, которая будет выполнена с параметрами remove_handle и arg при выходе текущей среды Node.js.

В отличие от napi_add_env_cleanup_hook, обработчик может быть асинхронным.

В остальном поведение в целом соответствует napi_add_env_cleanup_hook.

Если remove_handle не NULL, в нём будет храниться значение, которое позже необходимо передать в napi_remove_async_cleanup_hook, независимо от того, был ли обработчик уже вызван. Как правило, это происходит при разборке ресурса, для которого был добавлен этот обработчик.

napi_remove_async_cleanup_hook
История
Версия Изменения
v14.10.0, v12.19.0

Удалён параметр env.

v14.8.0, v12.19.0

Добавлен в: v14.8.0, v12.19.0

NAPI_EXTERN napi_status napi_remove_async_cleanup_hook(
    napi_async_cleanup_hook_handle remove_handle); copy
  • [in] remove_handle: Ручка асинхронного обработчика очистки, созданного с помощью napi_add_async_cleanup_hook.

Отменяет регистрацию обработчика очистки, соответствующего remove_handle. Это предотвратит выполнение обработчика, если он ещё не начал выполняться. Это необходимо вызвать для любого значения napi_async_cleanup_hook_handle , полученного из napi_add_async_cleanup_hook.

Финализация при выходе из среды Node.js

Среда Node.js может быть закрыта в произвольный момент, как только это возможно, с запретом выполнения JavaScript, например, по запросу worker.terminate(). Когда среда закрывается, зарегистрированные обратные вызовы napi_finalize обратных вызовов JavaScript-объектов, потокобезопасных функций и данных экземпляра среды вызываются немедленно и независимо.

Вызов обратных вызовов napi_finalize запланирован после вручную зарегистрированных обработчиков очистки. Чтобы обеспечить правильный порядок финализации дополнений во время завершения среды, чтобы избежать использования после освобождения в обратном вызове napi_finalize, дополнения должны зарегистрировать обработчик очистки с помощью napi_add_env_cleanup_hook и napi_add_async_cleanup_hook для ручного освобождения выделенных ресурсов в правильном порядке.

Регистрация модулей

Модули Node-API регистрируются аналогично другим модулям, за исключением того, что вместо использования макроса NODE_MODULE используется следующее:

NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) copy

Следующее различие — сигнатура метода Init. Для модуля Node-API она выглядит следующим образом:

napi_value Init(napi_env env, napi_value exports); copy

Значение, возвращаемое из Init, обрабатывается как объект exports для модуля. Методу Init передаётся пустой объект через параметр exports для удобства. Если Init возвращает NULL, параметр, переданный как exports, экспортируется модулем. Модули Node-API не могут изменять объект module, но могут указать что угодно в качестве свойства exports модуля.

Для добавления метода hello как функции, чтобы его можно было вызывать как метод, предоставляемый дополнением:

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;
} copy

Для задания функции, которая должна возвращаться методом require() для дополнения:

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;
} copy

Для определения класса, чтобы можно было создавать новые экземпляры (часто используется с 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;
} copy

Вы также можете использовать макрос NAPI_MODULE_INIT, который служит сокращением для NAPI_MODULE и определения функции Init:

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;
} copy

Все дополнения Node-API осознают контекст, что означает, что их можно загружать несколько раз. При объявлении такого модуля следует учитывать несколько аспектов дизайна. Более подробная информация содержится в документации по модулям дополнений, осознающим контекст.

Переменные env и exports будут доступны внутри тела функции после вызова макроса.

Дополнительные сведения о настройке свойств объектов см. в разделе Работа со свойствами JavaScript.

Дополнительные сведения о создании модулей дополнений в целом см. в существующей API.

END_OF_DOCUMENT_MARKER

Работа с JavaScript-значениями

Node-API предоставляет набор API для создания всех типов JavaScript-значений. Некоторые из этих типов документированы в разделе 6 Спецификации языка ECMAScript.

В основном эти API используются для одного из следующих действий:

  1. Создание нового JavaScript-объекта
  2. Преобразование из примитивного типа C в значение Node-API
  3. Преобразование из значения Node-API в примитивный тип C
  4. Получение глобальных экземпляров, включая undefined и null

Значения Node-API представляются типом napi_value. Любой вызов Node-API, требующий JavaScript-значения, принимает napi_value. В некоторых случаях API предварительно проверяет тип napi_value. Однако для лучшей производительности лучше, чтобы вызывающая сторона убедилась, что napi_value имеет ожидаемый JavaScript-тип, необходимый API.

Типы перечислений

napi_key_collection_mode
Добавлен в: v13.7.0, v12.17.0, v10.20.0 Версия N-API: 6
typedef enum {
  napi_key_include_prototypes,
  napi_key_own_only
} napi_key_collection_mode; copy

Описывает перечисления фильтров Keys/Properties:

napi_key_collection_mode ограничивает диапазон собранных свойств.

napi_key_own_only ограничивает собранные свойства только данным объектом. napi_key_include_prototypes также включит все ключи цепочки прототипов объекта.

napi_key_filter
Добавлен в: v13.7.0, v12.17.0, v10.20.0 Версия N-API: 6
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; copy

Биты фильтра свойств. Их можно объединить операцией OR для создания составного фильтра.

napi_key_conversion
Добавлен в: v13.7.0, v12.17.0, v10.20.0 Версия N-API: 6
typedef enum {
  napi_key_keep_numbers,
  napi_key_numbers_to_strings
} napi_key_conversion; copy

napi_key_numbers_to_strings преобразует целочисленные индексы в строки. napi_key_keep_numbers вернет числа для целочисленных индексов.

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; copy

Описывает тип napi_value. В целом это соответствует типам, описанным в разделе 6.1 Спецификации языка ECMAScript. В дополнение к типам в этом разделе napi_valuetype также может представлять Function и Object с внешними данными.

JavaScript-значение типа napi_external отображается в JavaScript как обычный объект, к которому нельзя назначать свойства и у которого нет прототипа.

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; copy

Это представляет собой базовый бинарный скалярный тип данных TypedArray. Элементы этого перечисления соответствуют разделу 22.2 Спецификации языка ECMAScript.

Функции создания объектов

napi_create_array
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_create_array(napi_env env, napi_value* result) copy
  • [in] env: Среда, в которой вызывается вызов Node-API.
  • [out] result: napi_value, представляющий JavaScript-Array.

Возвращает napi_ok в случае успешного выполнения API.

Этот API возвращает значение Node-API, соответствующее JavaScript-типу Array. JavaScript-массивы описаны в разделе 22.1 Спецификации языка ECMAScript.

napi_create_array_with_length
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_create_array_with_length(napi_env env,
                                          size_t length,
                                          napi_value* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] length: Начальная длина Array.
  • [out] result: napi_value, представляющий JavaScript-Array.

Возвращает napi_ok в случае успешного выполнения API.

Этот API возвращает значение Node-API, соответствующее JavaScript-типу Array. Свойство length Array устанавливается в переданное значение length. Однако гарантии предварительной выделения буфера для массива в памяти виртуальной машиной при создании нет. Это зависит от реализации виртуальной машины. Если буфер должен быть непрерывным блоком памяти, к которому можно напрямую обращаться и/или записывать из C, используйте napi_create_external_arraybuffer.

JavaScript-массивы описаны в разделе 22.1 Спецификации языка ECMAScript.

napi_create_arraybuffer
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_create_arraybuffer(napi_env env,
                                    size_t byte_length,
                                    void** data,
                                    napi_value* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] length: Длина в байтах создаваемого буфера массива.
  • [out] data: Указатель на базовый байтовый буфер ArrayBuffer . data можно необязательно пропустить, передав NULL.
  • [out] result: napi_value, представляющий JavaScript-ArrayBuffer.

Возвращает napi_ok в случае успешного выполнения API.

Этот API возвращает значение Node-API, соответствующее JavaScript-объекту ArrayBuffer. ArrayBuffer используются для представления буферов фиксированной длины бинарных данных. Обычно они используются в качестве буфера для объектов TypedArray. Выделенный ArrayBuffer будет иметь базовый байтовый буфер размером, определенным параметром length. Необязательно возвращать базовый буфер вызывающей стороне, если она хочет напрямую манипулировать буфером. К этому буферу можно записывать напрямую только из кода нативных языках. Для записи в этот буфер из JavaScript необходимо создать массив или объект DataView.

JavaScript-объекты ArrayBuffer описаны в разделе 24.1 Спецификации языка ECMAScript.

napi_create_buffer
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_create_buffer(napi_env env,
                               size_t size,
                               void** data,
                               napi_value* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] size: Размер базового буфера в байтах.
  • [out] data: Сырой указатель на базовый буфер. data можно необязательно пропустить, передав NULL.
  • [out] result: napi_value, представляющий node::Buffer.

Возвращает napi_ok в случае успешного выполнения API.

Этот API выделяет объект node::Buffer. Хотя эта структура по-прежнему полностью поддерживается, в большинстве случаев достаточно использовать TypedArray.

napi_create_buffer_copy
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_create_buffer_copy(napi_env env,
                                    size_t length,
                                    const void* data,
                                    void** result_data,
                                    napi_value* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] size: Размер входного буфера в байтах (должен быть таким же, как размер нового буфера).
  • [in] data: Сырой указатель на исходный буфер для копирования.
  • [out] result_data: Указатель на базовый буфер данных нового Buffer. result_data можно необязательно пропустить, передав NULL.
  • [out] result: napi_value, представляющий node::Buffer.

Возвращает napi_ok в случае успешного выполнения API.

Этот API выделяет объект node::Buffer и инициализирует его данными, скопированными из переданного буфера. Хотя эта структура по-прежнему полностью поддерживается, в большинстве случаев достаточно использовать TypedArray.

napi_create_date
Добавлен в: v11.11.0, v10.17.0 Версия N-API: 5
napi_status napi_create_date(napi_env env,
                             double time,
                             napi_value* result); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] time: Значение времени ECMAScript в миллисекундах с момента 01 января 1970 года по UTC.
  • [out] result: napi_value, представляющий JavaScript-Date.

Возвращает napi_ok в случае успешного выполнения API.

Этот API не учитывает високосные секунды; они игнорируются, поскольку ECMAScript соответствует спецификации времени POSIX.

Этот API выделяет объект JavaScript Date.

JavaScript-объекты Date описаны в разделе 20.3 Спецификации языка ECMAScript.

napi_create_external
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_create_external(napi_env env,
                                 void* data,
                                 napi_finalize finalize_cb,
                                 void* finalize_hint,
                                 napi_value* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] data: Сырой указатель на внешние данные.
  • [in] finalize_cb: Необязательный обратный вызов, который вызывается при сборе внешнего значения. napi_finalize содержит дополнительные сведения.
  • [in] finalize_hint: Необязательный параметр, передаваемый обратному вызову finalize при сборе.
  • [out] result: napi_value, представляющий внешнее значение.

Возвращает napi_ok в случае успешного выполнения API.

Этот API выделяет JavaScript-значение с прикрепленными к нему внешними данными. Это используется для передачи внешних данных через JavaScript-код, чтобы их можно было получить позже в коде нативных языках с помощью napi_get_value_external.

API добавляет обратный вызов napi_finalize, который вызывается, когда созданный JavaScript-объект был собран системой сборки мусора.

Созданное значение не является объектом и, следовательно, не поддерживает дополнительные свойства. Это считается отдельным типом значения: вызов napi_typeof() с внешним значением возвращает napi_external.

napi_create_external_arraybuffer
Добавлен в: v8.0.0 Версия N-API: 1
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) copy
END_OF_DOCUMENT_MARKER
  • [in] env: Окружение, в котором вызывается API.
  • [in] external_data: Указатель на основной буфер байтов ArrayBuffer.
  • [in] byte_length: Длина основного буфера в байтах.
  • [in] finalize_cb: Необязательный обратный вызов, вызываемый при сборке мусора ArrayBuffer. napi_finalize содержит больше информации.
  • [in] finalize_hint: Необязательный параметр для передачи в обратный вызов finalize при сборке мусора.
  • [out] result: napi_value, представляющий JavaScript ArrayBuffer.

Возвращает napi_ok в случае успешного выполнения API.

Некоторые среды выполнения, отличные от Node.js, отказались от поддержки внешних буферов. В средах выполнения, отличных от Node.js, этот метод может возвращать napi_no_external_buffers_allowed для указания того, что внешние буферы не поддерживаются. Одним из таких сред выполнения является Electron, как описано в этой проблеме electron/issues/35801.

Для обеспечения максимальной совместимости со всеми средами выполнения вы можете определить NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED в своём дополнении перед включением заголовков node-api. Это скроет две функции, создающие внешние буферы. Это гарантирует, что произойдет ошибка компиляции, если вы случайно используете один из этих методов.

Этот API возвращает значение Node-API, соответствующее JavaScript ArrayBuffer. Основной буфер байтов ArrayBuffer выделяется и управляется вне среды выполнения. Вызывающая сторона должна гарантировать, что буфер байтов остаётся корректным до вызова обратного вызова finalize.

API добавляет обратный вызов napi_finalize, который будет вызван при сборе мусора только что созданного JavaScript-объекта.

JavaScript ArrayBuffer описаны в Разделе 24.1 спецификации языка ECMAScript.

napi_create_external_buffer
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_create_external_buffer(napi_env env,
                                        size_t length,
                                        void* data,
                                        napi_finalize finalize_cb,
                                        void* finalize_hint,
                                        napi_value* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] length: Размер входного буфера в байтах (должен быть таким же, как размер нового буфера).
  • [in] data: Сырой указатель на основной буфер для экспонирования в JavaScript.
  • [in] finalize_cb: Необязательный обратный вызов, вызываемый при сборке мусора ArrayBuffer. napi_finalize содержит больше информации.
  • [in] finalize_hint: Необязательный параметр для передачи в обратный вызов finalize при сборке мусора.
  • [out] result: napi_value, представляющий node::Buffer.

Возвращает napi_ok в случае успешного выполнения API.

Некоторые среды выполнения, отличные от Node.js, отказались от поддержки внешних буферов. В средах выполнения, отличных от Node.js, этот метод может возвращать napi_no_external_buffers_allowed для указания того, что внешние буферы не поддерживаются. Одним из таких сред выполнения является Electron, как описано в этой проблеме electron/issues/35801.

Для обеспечения максимальной совместимости со всеми средами выполнения вы можете определить NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED в своём дополнении перед включением заголовков node-api. Это скроет две функции, создающие внешние буферы. Это гарантирует, что произойдет ошибка компиляции, если вы случайно используете один из этих методов.

Этот API выделяет объект node::Buffer и инициализирует его данными, основанными на переданном буфере. Хотя это по-прежнему полностью поддерживаемая структура данных, в большинстве случаев достаточно использовать TypedArray.

API добавляет обратный вызов napi_finalize , который будет вызван при сборе мусора только что созданного JavaScript-объекта.

Для Node.js >=4 Buffers являются Uint8Array.

napi_create_object
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_create_object(napi_env env, napi_value* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [out] result: napi_value, представляющий JavaScript Object.

Возвращает napi_ok в случае успешного выполнения API.

Этот API выделяет стандартный JavaScript Object. Он эквивалентен выполнению new Object() в JavaScript.

Тип JavaScript Object описан в Разделе 6.1.7 спецификации языка ECMAScript.

napi_create_symbol
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_create_symbol(napi_env env,
                               napi_value description,
                               napi_value* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] description: Необязательное napi_value, которое ссылается на JavaScript string для установки в качестве описания символа.
  • [out] result: napi_value, представляющий JavaScript symbol.

Возвращает napi_ok в случае успешного выполнения API.

Этот API создаёт значение JavaScript symbol из UTF8-кодированной C-строки.

Тип JavaScript symbol описан в Разделе 19.4 спецификации языка ECMAScript.

node_api_symbol_for
Добавлен в: v17.5.0 Версия N-API: 9
napi_status node_api_symbol_for(napi_env env,
                                const char* utf8description,
                                size_t length,
                                napi_value* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] utf8description: UTF-8 C-строка, представляющая текст, используемый в качестве описания для символа.
  • [in] length: Длина строки описания в байтах или NAPI_AUTO_LENGTH, если она имеет нуль-терминацию.
  • [out] result: napi_value, представляющий JavaScript symbol.

Возвращает napi_ok в случае успешного выполнения API.

Этот API ищет в глобальном реестре существующий символ с данным описанием. Если символ уже существует, он возвращается; в противном случае создаётся новый символ в реестре.

Тип JavaScript symbol описан в Разделе 19.4 спецификации языка ECMAScript.

napi_create_typedarray
Добавлен в: v8.0.0 Версия N-API: 1
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) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] type: Скалируемый тип данных элементов внутри TypedArray.
  • [in] length: Количество элементов в TypedArray.
  • [in] arraybuffer: ArrayBuffer в основе массива с типом.
  • [in] byte_offset: Смещение в байтах внутри ArrayBuffer, с которого начинается отображение TypedArray.
  • [out] result: napi_value, представляющий JavaScript TypedArray.

Возвращает napi_ok в случае успешного выполнения API.

Этот API создаёт JavaScript-объект TypedArray над существующим ArrayBuffer . Объекты TypedArray предоставляют массивоподобный вид на основной буфер данных, где каждый элемент имеет тот же базовый двоичный скалярный тип данных.

Необходимо, чтобы (length * size_of_element) + byte_offset было меньше или равно размеру в байтах переданного массива. В противном случае возникает исключение RangeError.

Объекты JavaScript TypedArray описаны в Разделе 22.2 спецификации языка ECMAScript.

napi_create_dataview
Добавлен в: v8.3.0 Версия N-API: 1
napi_status napi_create_dataview(napi_env env,
                                 size_t byte_length,
                                 napi_value arraybuffer,
                                 size_t byte_offset,
                                 napi_value* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] length: Количество элементов в DataView.
  • [in] arraybuffer: ArrayBuffer в основе DataView.
  • [in] byte_offset: Смещение в байтах внутри ArrayBuffer, с которого начинается отображение DataView.
  • [out] result: napi_value, представляющий JavaScript DataView.

Возвращает napi_ok в случае успешного выполнения API.

Этот API создает JavaScript DataView объект над существующим ArrayBuffer . Объекты DataView обеспечивают массивоподобный вид на основной буфер данных, но позволяют использовать элементы разного размера и типа в ArrayBuffer.

Требуется, чтобы byte_length + byte_offset было меньше или равно размеру в байтах переданного массива. В противном случае генерируется исключение RangeError.

Объекты JavaScript DataView описаны в Разделе 24.3 спецификации языка ECMAScript.

Функции для преобразования из C-типов в Node-API

napi_create_int32
Добавлен в: v8.4.0 Версия N-API: 1
napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: Целочисленное значение для представления в JavaScript.
  • [out] result: napi_value, представляющий JavaScript number.

Возвращает napi_ok в случае успешного выполнения API.

Этот API используется для преобразования типа C int32_t в тип JavaScript number.

Тип JavaScript number описан в Разделе 6.1.6 спецификации языка ECMAScript.

napi_create_uint32
Добавлен в: v8.4.0 Версия N-API: 1
napi_status napi_create_uint32(napi_env env, uint32_t value, napi_value* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: Беззнаковое целое значение для представления в JavaScript.
  • [out] result: napi_value, представляющий JavaScript number.

Возвращает napi_ok в случае успешного выполнения API.

Этот API используется для преобразования типа C uint32_t в тип JavaScript number.

Тип JavaScript number описан в разделе 6.1.6 спецификации языка ECMAScript.

napi_create_int64
Добавлен в: v8.4.0 Версия N-API: 1
napi_status napi_create_int64(napi_env env, int64_t value, napi_value* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: Целочисленное значение, подлежащее представлению в JavaScript.
  • [out] result: Объект napi_value , представляющий JavaScript-тип number.

Возвращает napi_ok в случае успешного выполнения API.

Этот API используется для преобразования типа C int64_t в тип JavaScript number.

Тип JavaScript number описан в разделе 6.1.6 спецификации языка ECMAScript. Обратите внимание, что полный диапазон int64_t не может быть представлен с полной точностью в JavaScript. Целочисленные значения, выходящие за пределы диапазона Number.MIN_SAFE_INTEGER -(2**53 - 1) - Number.MAX_SAFE_INTEGER (2**53 - 1) , потеряют точность.

napi_create_double
Добавлен в: v8.4.0 Версия N-API: 1
napi_status napi_create_double(napi_env env, double value, napi_value* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: Значение двойной точности, подлежащее представлению в JavaScript.
  • [out] result: Объект napi_value , представляющий JavaScript-тип number.

Возвращает napi_ok в случае успешного выполнения API.

Этот API используется для преобразования типа C double в тип JavaScript number.

Тип JavaScript number описан в разделе 6.1.6 спецификации языка ECMAScript.

napi_create_bigint_int64
Добавлен в: v10.7.0 Версия N-API: 6
napi_status napi_create_bigint_int64(napi_env env,
                                     int64_t value,
                                     napi_value* result); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: Целочисленное значение, подлежащее представлению в JavaScript.
  • [out] result: Объект napi_value , представляющий JavaScript-тип BigInt.

Возвращает napi_ok в случае успешного выполнения API.

Этот API преобразует тип C int64_t в тип JavaScript BigInt.

napi_create_bigint_uint64
Добавлен в: v10.7.0 Версия N-API: 6
napi_status napi_create_bigint_uint64(napi_env env,
                                      uint64_t value,
                                      napi_value* result); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: Беззнаковое целочисленное значение, подлежащее представлению в JavaScript.
  • [out] result: Объект napi_value , представляющий JavaScript-тип BigInt.

Возвращает napi_ok в случае успешного выполнения API.

Этот API преобразует тип C uint64_t в тип JavaScript BigInt.

napi_create_bigint_words
Добавлен в: v10.7.0 Версия N-API: 6
napi_status napi_create_bigint_words(napi_env env,
                                     int sign_bit,
                                     size_t word_count,
                                     const uint64_t* words,
                                     napi_value* result); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] sign_bit: Определяет, будет ли полученное BigInt положительным или отрицательным.
  • [in] word_count: Длина массива words.
  • [in] words: Массив uint64_t слов с малой эндианностью 64-разрядной точности.
  • [out] result: Объект napi_value , представляющий JavaScript-тип BigInt.

Возвращает napi_ok в случае успешного выполнения API.

Этот API преобразует массив беззнаковых 64-битных слов в единое значение BigInt.

Полученное значение BigInt вычисляется как: (–1)sign_bit (words[0] × (264)0 + words[1] × (264)1 + …)

napi_create_string_latin1
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_create_string_latin1(napi_env env,
                                      const char* str,
                                      size_t length,
                                      napi_value* result); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] str: Буфер символов, представляющий строку в кодировке ISO-8859-1.
  • [in] length: Длина строки в байтах или NAPI_AUTO_LENGTH , если она завершается нулём.
  • [out] result: Объект napi_value , представляющий JavaScript-тип string.

Возвращает napi_ok в случае успешного выполнения API.

Этот API создает значение JavaScript string из C-строки, закодированной в ISO-8859-1. Оригинальная строка копируется.

Тип JavaScript string описан в разделе 6.1.4 спецификации языка ECMAScript.

node_api_create_external_string_latin1
Добавлен в: v18.18.0
Устойчивость: 1 - Экспериментальная
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); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] str: Буфер символов, представляющий строку в кодировке ISO-8859-1.
  • [in] length: Длина строки в байтах или NAPI_AUTO_LENGTH , если она завершается нулём.
  • [in] finalize_callback: Функция, которая вызывается при сборке мусора строки. Функция будет вызвана со следующими параметрами:
    • [in] env: Среда, в которой выполняется плагин. Это значение может быть null, если строка собирается в процессе завершения работы worker или основного экземпляра Node.js.
    • [in] data: Это значение str как указатель на тип void*.
    • [in] finalize_hint: Это значение finalize_hint , которое было передано в API. napi_finalize содержит более подробную информацию. Этот параметр является необязательным. Передача null означает, что плагин не нуждается в уведомлении при сборе мусора соответствующей JavaScript-строки.
  • [in] finalize_hint: Необязательное значение, передаваемое в обратный вызов finalize при сборе мусора.
  • [out] result: Объект napi_value , представляющий JavaScript-тип string.
  • [out] copied: Была ли скопирована строка. Если да, finalizer уже был вызван для удаления str.

Возвращает napi_ok в случае успешного выполнения API.

Этот API создает значение JavaScript string из C-строки, закодированной в ISO-8859-1. Оригинальная строка может не копироваться и должна существовать на протяжении всего жизненного цикла JavaScript-значения.

Тип JavaScript string описан в разделе 6.1.4 спецификации языка ECMAScript.

napi_create_string_utf16
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_create_string_utf16(napi_env env,
                                     const char16_t* str,
                                     size_t length,
                                     napi_value* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] str: Буфер символов, представляющий строку в кодировке UTF16-LE.
  • [in] length: Длина строки в двухбайтовых кодовых единицах или NAPI_AUTO_LENGTH , если она завершается нулём.
  • [out] result: Объект napi_value , представляющий JavaScript-тип string.

Возвращает napi_ok в случае успешного выполнения API.

Этот API создает значение JavaScript string из C-строки, закодированной в UTF16-LE. Оригинальная строка копируется.

Тип JavaScript string описан в разделе 6.1.4 спецификации языка ECMAScript.

node_api_create_external_string_utf16
Добавлен в: v18.18.0
Устойчивость: 1 - Экспериментальная
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); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] str: Буфер символов, представляющий строку в кодировке UTF16-LE.
  • [in] length: Длина строки в двухбайтовых кодовых единицах или NAPI_AUTO_LENGTH , если она завершается нулём.
  • [in] finalize_callback: Функция, которая вызывается при сборке мусора строки. Функция будет вызвана со следующими параметрами:
    • [in] env: Среда, в которой выполняется плагин. Это значение может быть null, если строка собирается в процессе завершения работы worker или основного экземпляра Node.js.
    • [in] data: Это значение str как указатель на тип void*.
    • [in] finalize_hint: Это значение finalize_hint , которое было передано в API. napi_finalize содержит более подробную информацию. Этот параметр является необязательным. Передача null означает, что плагин не нуждается в уведомлении при сборе мусора соответствующей JavaScript-строки.
  • [in] finalize_hint: Необязательное значение, передаваемое в обратный вызов finalize при сборе мусора.
  • [out] result: Объект napi_value , представляющий JavaScript-тип string.
  • [out] copied: Была ли скопирована строка. Если да, finalizer уже был вызван для удаления str.

Возвращает napi_ok в случае успешного выполнения API.

Этот API создает значение JavaScript string из C-строки, закодированной в UTF16-LE. Оригинальная строка может не копироваться и должна существовать на протяжении всего жизненного цикла JavaScript-значения.

Тип JavaScript string описан в разделе 6.1.4 спецификации языка ECMAScript.

napi_create_string_utf8
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_create_string_utf8(napi_env env,
                                    const char* str,
                                    size_t length,
                                    napi_value* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] str: Буфер символов, представляющий строку UTF8.
  • [in] length: Длина строки в байтах или NAPI_AUTO_LENGTH в случае завершения нулём.
  • [out] result: Объект napi_value , представляющий JavaScript string.

Возвращает napi_ok в случае успешного выполнения API.

Этот API создаёт значение JavaScript string из строки C, закодированной в UTF8. Исходная строка копируется.

Тип JavaScript string описан в разделе 6.1.4 спецификации ECMAScript Language Specification.

Функции для преобразования из Node-API в типы C

napi_get_array_length
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_array_length(napi_env env,
                                  napi_value value,
                                  uint32_t* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: Объект napi_value , представляющий JavaScript Array , длина которого запрашивается.
  • [out] result: Объект uint32 , представляющий длину массива.

Возвращает napi_ok в случае успешного выполнения API.

Этот API возвращает длину массива.

Длина Array описана в разделе 22.1.4.1 спецификации ECMAScript Language Specification.

napi_get_arraybuffer_info
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_arraybuffer_info(napi_env env,
                                      napi_value arraybuffer,
                                      void** data,
                                      size_t* byte_length) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] arraybuffer: Объект napi_value , представляющий запрашиваемый ArrayBuffer.
  • [out] data: Базовый буфер данных ArrayBuffer . Если byte_length равно 0, он может быть NULL или любым другим значением указателя.
  • [out] byte_length: Длина базового буфера данных в байтах.

Возвращает napi_ok в случае успешного выполнения API.

Этот API используется для получения базового буфера данных ArrayBuffer и его длины.

ПРЕДУПРЕЖДЕНИЕ: При использовании этого API будьте осторожны. Жизненный цикл базового буфера данных управляется ArrayBuffer даже после его возврата. Возможно безопасный способ использования этого API — в сочетании с napi_create_reference, которое может гарантировать контроль над жизненным циклом ArrayBuffer . Также безопасно использовать возвращённый буфер данных в рамках того же обратного вызова, пока не выполняются другие API, которые могут вызвать сборку мусора.

napi_get_buffer_info
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_buffer_info(napi_env env,
                                 napi_value value,
                                 void** data,
                                 size_t* length) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: Объект napi_value , представляющий запрашиваемый node::Buffer.
  • [out] data: Базовый буфер данных node::Buffer . Если длина равна 0, этот буфер может быть NULL или любым другим значением указателя.
  • [out] length: Длина базового буфера данных в байтах.

Возвращает napi_ok в случае успешного выполнения API.

Этот API используется для получения базового буфера данных node::Buffer и его длины.

Предупреждение: Будьте осторожны при использовании этого API, поскольку жизненный цикл базового буфера данных не гарантируется, если он управляется виртуальной машиной.

napi_get_prototype
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_prototype(napi_env env,
                               napi_value object,
                               napi_value* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] object: Объект napi_value , представляющий JavaScript Object , прототип которого нужно вернуть. Это возвращает эквивалент Object.getPrototypeOf (что не то же самое, что свойство prototype функции).
  • [out] result: Объект napi_value , представляющий прототип заданного объекта.

Возвращает napi_ok в случае успешного выполнения API.

napi_get_typedarray_info
Добавлена в: v8.0.0 Версия N-API: 1
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) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] typedarray: Объект napi_value , представляющий TypedArray , чьи свойства запрашиваются.
  • [out] type: Скалярный тип данных элементов в TypedArray.
  • [out] length: Количество элементов в TypedArray.
  • [out] data: Буфер данных, лежащий в основе TypedArray , скорректированный значением byte_offset, так что он указывает на первый элемент в TypedArray . Если длина массива 0, он может быть NULL или любым другим значением указателя.
  • [out] arraybuffer: Тип ArrayBuffer , лежащий в основе TypedArray.
  • [out] byte_offset: Смещение в байтах в базовом массиве, от которого начинается проектирование первого элемента массивов. Значение для параметра data уже было скорректировано, поэтому data указывает на первый элемент в массиве. Следовательно, первый байт базового массива будет в data - byte_offset.

Возвращает napi_ok в случае успешного выполнения API.

Этот API возвращает различные свойства массива с типом данных.

Любой из выходных параметров может быть NULL , если это свойство не нужно.

Предупреждение: Будьте осторожны при использовании этого API, поскольку базовый буфер данных управляется виртуальной машиной.

napi_get_dataview_info
Добавлена в: v8.3.0 Версия N-API: 1
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) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] dataview: Объект napi_value , представляющий DataView , чьи свойства запрашиваются.
  • [out] byte_length: Количество байтов в DataView.
  • [out] data: Буфер данных, лежащий в основе DataView . Если byte_length равно 0, он может быть NULL или любым другим значением указателя.
  • [out] arraybuffer: Тип ArrayBuffer , лежащий в основе DataView.
  • [out] byte_offset: Смещение в байтах в буфере данных, от которого начинается проектирование DataView.

Возвращает napi_ok в случае успешного выполнения API.

Любой из выходных параметров может быть NULL , если это свойство не нужно.

Этот API возвращает различные свойства DataView.

napi_get_date_value
Добавлена в: v11.11.0, v10.17.0 Версия N-API: 5
napi_status napi_get_date_value(napi_env env,
                                napi_value value,
                                double* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: Объект napi_value , представляющий JavaScript Date.
  • [out] result: Значение времени в виде double , представленного в миллисекундах с полуночи начала 01 января 1970 года по UTC.

Этот API не учитывает високосные секунды; они игнорируются, так как ECMAScript соответствует спецификации времени POSIX.

Возвращает napi_ok в случае успешного выполнения API. Если передан не объект даты, napi_value, возвращается napi_date_expected.

Этот API возвращает значение типа C double для значения времени заданного JavaScript Date.

napi_get_value_bool
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_value_bool(napi_env env, napi_value value, bool* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: Объект napi_value , представляющий JavaScript Boolean.
  • [out] result: Эквивалент C булевого типа для данного JavaScript Boolean.

Возвращает napi_ok в случае успешного выполнения API. Если передан не булев тип napi_value , возвращается napi_boolean_expected.

Этот API возвращает эквивалент C булевого типа для данного JavaScript Boolean.

napi_get_value_double
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_value_double(napi_env env,
                                  napi_value value,
                                  double* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: Объект napi_value , представляющий JavaScript number.
  • [out] result: Эквивалент C double для данного JavaScript number.

Возвращает napi_ok в случае успешного выполнения API. Если передан не числовой тип napi_value , возвращается napi_number_expected.

Этот API возвращает эквивалент C double для данного JavaScript number.

napi_get_value_bigint_int64
Добавлена в: v10.7.0 Версия N-API: 6
napi_status napi_get_value_bigint_int64(napi_env env,
                                        napi_value value,
                                        int64_t* result,
                                        bool* lossless); copy
  • [in] env: Окружение, в котором вызывается API
  • [in] value: Объект napi_value , представляющий JavaScript BigInt.
  • [out] result: C int64_t эквивалент для данного JavaScript BigInt.
  • [out] lossless: Указывает, было ли значение BigInt преобразовано без потерь.

Возвращает napi_ok в случае успешного выполнения API. Если передан не BigInt , возвращается napi_bigint_expected.

Этот API возвращает C int64_t эквивалент для данного JavaScript BigInt . При необходимости он обрезает значение, устанавливая lossless в false.

napi_get_value_bigint_uint64
Добавлена в: v10.7.0 Версия N-API: 6
napi_status napi_get_value_bigint_uint64(napi_env env,
                                        napi_value value,
                                        uint64_t* result,
                                        bool* lossless); copy
END_OF_DOCUMENT_MARKER
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: napi_value представляющее JavaScript BigInt.
  • [out] result: C uint64_t примитивный эквивалент данного JavaScript BigInt.
  • [out] lossless: Указывает, была ли преобразована BigInt величина без потерь.

Возвращает napi_ok если API выполнилось успешно. Если передан не-BigInt тип, возвращает napi_bigint_expected.

Этот API возвращает C uint64_t примитивный эквивалент данного JavaScript BigInt. При необходимости, он обрезает значение, устанавливая lossless в false.

napi_get_value_bigint_words
Добавлена в: v10.7.0 Версия N-API: 6
napi_status napi_get_value_bigint_words(napi_env env,
                                        napi_value value,
                                        int* sign_bit,
                                        size_t* word_count,
                                        uint64_t* words); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: napi_value представляющее JavaScript BigInt.
  • [out] sign_bit: Целое число, представляющее положительный или отрицательный знак JavaScript BigInt.
  • [in/out] word_count: Должен быть инициализирован длиной массива words . При возврате он будет установлен на фактическое количество слов, необходимых для хранения этой BigInt.
  • [out] words: Указатель на предварительно выделенный массив 64-битных слов.

Возвращает napi_ok если API выполнилось успешно.

Этот API преобразует значение одиночного BigInt в бит знака, 64-битный массив little-endian и количество элементов в массиве. sign_bit и words могут быть оба установлены в NULL, чтобы получить только word_count.

napi_get_value_external
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_value_external(napi_env env,
                                    napi_value value,
                                    void** result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: napi_value представляющее внешнее значение JavaScript.
  • [out] result: Указатель на данные, обернутые внешним значением JavaScript.

Возвращает napi_ok если API выполнилось успешно. Если передан не-внешний napi_value тип, возвращает napi_invalid_arg.

Этот API извлекает указатель на внешние данные, которые были ранее переданы в napi_create_external().

napi_get_value_int32
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_value_int32(napi_env env,
                                 napi_value value,
                                 int32_t* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: napi_value представляющее JavaScript number.
  • [out] result: C int32 примитивный эквивалент данного JavaScript number.

Возвращает napi_ok если API выполнилось успешно. Если передан нечисловой napi_value тип, возвращается napi_number_expected.

Этот API возвращает C int32 примитивный эквивалент данного JavaScript number.

Если число выходит за пределы диапазона 32-битного целого числа, результат усекается до эквивалента нижних 32 битов. Это может привести к тому, что большое положительное число станет отрицательным, если значение больше, чем 231 - 1.

Неконечные числовые значения (NaN, +Infinity, или -Infinity) устанавливают результат в ноль.

napi_get_value_int64
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_value_int64(napi_env env,
                                 napi_value value,
                                 int64_t* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: napi_value представляющее JavaScript number.
  • [out] result: C int64 примитивный эквивалент данного JavaScript number.

Возвращает napi_ok если API выполнилось успешно. Если передан нечисловой napi_value тип, возвращает napi_number_expected.

Этот API возвращает C int64 примитивный эквивалент данного JavaScript number.

Значения number вне диапазона Number.MIN_SAFE_INTEGER -(2**53 - 1) - Number.MAX_SAFE_INTEGER (2**53 - 1) будут терять точность.

Неконечные числовые значения (NaN, +Infinity, или -Infinity) устанавливают результат в ноль.

napi_get_value_string_latin1
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_value_string_latin1(napi_env env,
                                         napi_value value,
                                         char* buf,
                                         size_t bufsize,
                                         size_t* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: napi_value представляющее JavaScript строку.
  • [in] buf: Буфер для записи строки ISO-8859-1. Если NULL передан, длина строки в байтах, исключая нулевой терминатор, возвращается в result.
  • [in] bufsize: Размер буфера назначения. Если этого значения недостаточно, возвращаемая строка усекается и завершается нулём.
  • [out] result: Количество скопированных в буфер байтов, исключая нулевой терминатор.

Возвращает napi_ok если API выполнилось успешно. Если передан не-string napi_value тип, возвращает napi_string_expected.

Этот API возвращает строку, закодированную в ISO-8859-1, соответствующую переданному значению.

napi_get_value_string_utf8
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_value_string_utf8(napi_env env,
                                       napi_value value,
                                       char* buf,
                                       size_t bufsize,
                                       size_t* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: napi_value представляющее JavaScript строку.
  • [in] buf: Буфер для записи UTF8-строки. Если NULL передан, длина строки в байтах, исключая нулевой терминатор, возвращается в result.
  • [in] bufsize: Размер буфера назначения. Если этого значения недостаточно, возвращаемая строка усекается и завершается нулём.
  • [out] result: Количество скопированных в буфер байтов, исключая нулевой терминатор.

Возвращает napi_ok если API выполнилось успешно. Если передан не-string napi_value тип, возвращает napi_string_expected.

Этот API возвращает строку, закодированную в UTF8, соответствующую переданному значению.

napi_get_value_string_utf16
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_value_string_utf16(napi_env env,
                                        napi_value value,
                                        char16_t* buf,
                                        size_t bufsize,
                                        size_t* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: napi_value представляющее JavaScript строку.
  • [in] buf: Буфер для записи строки UTF16-LE. Если NULL передан, длина строки в 2-байтовых кодовых единицах, исключая нулевой терминатор, возвращается.
  • [in] bufsize: Размер буфера назначения. Если этого значения недостаточно, возвращаемая строка усекается и завершается нулём.
  • [out] result: Количество 2-байтовых кодовых единиц, скопированных в буфер, исключая нулевой терминатор.

Возвращает napi_ok если API выполнилось успешно. Если передан не-string napi_value тип, возвращает napi_string_expected.

Этот API возвращает строку, закодированную в UTF16, соответствующую переданному значению.

napi_get_value_uint32
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_value_uint32(napi_env env,
                                  napi_value value,
                                  uint32_t* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: napi_value представляющее JavaScript number.
  • [out] result: C примитивный эквивалент данного napi_value как uint32_t.

Возвращает napi_ok если API выполнилось успешно. Если передан нечисловой napi_value тип, возвращает napi_number_expected.

Этот API возвращает C примитивный эквивалент данного napi_value как uint32_t.

Функции получения глобальных экземпляров

napi_get_boolean
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_boolean(napi_env env, bool value, napi_value* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: Значение булевого типа для извлечения.
  • [out] result: napi_value представляющее JavaScript Boolean синглтон для извлечения.

Возвращает napi_ok если API выполнилось успешно.

Этот API используется для возврата JavaScript синглтон-объекта, используемого для представления данного булевого значения.

napi_get_global
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_global(napi_env env, napi_value* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [out] result: napi_value представляющее JavaScript global объект.

Возвращает napi_ok если API выполнилось успешно.

Этот API возвращает global объект.

napi_get_null
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_null(napi_env env, napi_value* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [out] result: napi_value представляющее JavaScript null объект.

Возвращает napi_ok если API выполнилось успешно.

Этот API возвращает null объект.

napi_get_undefined
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_undefined(napi_env env, napi_value* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [out] result: napi_value представляющее значение JavaScript Undefined.

Возвращает napi_ok в случае успешного выполнения API.

Этот API возвращает объект Undefined.

Работа с JavaScript-значениями и абстрактными операциями

Node-API предоставляет набор API для выполнения некоторых абстрактных операций над JavaScript-значениями. Некоторые из этих операций описаны в разделе 7 спецификации языка ECMAScript ECMAScript Language Specification.

Эти API поддерживают выполнение одного из следующих действий:

  1. Приведение JavaScript-значений к определённым типам JavaScript (таким как number или string).
  2. Проверка типа JavaScript-значения.
  3. Проверка равенства двух JavaScript-значений.

napi_coerce_to_bool

Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_coerce_to_bool(napi_env env,
                                napi_value value,
                                napi_value* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: JavaScript-значение, которое необходимо привести к другому типу.
  • [out] result: napi_value представляющий приведенное к типу JavaScript Boolean.

Возвращает napi_ok если API выполнилась успешно.

Этот API реализует абстрактную операцию ToBoolean() как определено в разделе 7.1.2 спецификации языка ECMAScript.

napi_coerce_to_number

Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_coerce_to_number(napi_env env,
                                  napi_value value,
                                  napi_value* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: JavaScript-значение, которое необходимо привести к числу.
  • [out] result: napi_value представляющий приведенное к числу JavaScript number.

Возвращает napi_ok если API выполнилась успешно.

Этот API реализует абстрактную операцию ToNumber() как определено в разделе 7.1.3 спецификации языка ECMAScript. Эта функция потенциально выполняет JS-код, если переданное значение является объектом.

napi_coerce_to_object

Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_coerce_to_object(napi_env env,
                                  napi_value value,
                                  napi_value* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: JavaScript-значение, которое необходимо привести к объекту.
  • [out] result: napi_value представляющий приведенный к объекту JavaScript Object.

Возвращает napi_ok если API выполнилась успешно.

Этот API реализует абстрактную операцию ToObject() как определено в разделе 7.1.13 спецификации языка ECMAScript.

napi_coerce_to_string

Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_coerce_to_string(napi_env env,
                                  napi_value value,
                                  napi_value* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: JavaScript-значение, которое необходимо привести к строке.
  • [out] result: napi_value представляющий приведенную к строке JavaScript string.

Возвращает napi_ok если API выполнилась успешно.

Этот API реализует абстрактную операцию ToString() как определено в разделе 7.1.13 спецификации языка ECMAScript. Эта функция потенциально выполняет JS-код, если переданное значение является объектом.

napi_typeof

Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: JavaScript-значение, тип которого нужно получить.
  • [out] result: Тип JavaScript-значения.

Возвращает napi_ok если API выполнилась успешно.

  • napi_invalid_arg если тип value не является известным типом ECMAScript и value не является внешним значением.

Этот API представляет поведение, аналогичное вызову оператора typeof над объектом, как определено в разделе 12.5.5 спецификации языка ECMAScript. Однако существуют некоторые различия:

  1. Он поддерживает определение внешнего значения.
  2. Он определяет null как отдельный тип, в то время как ECMAScript typeof определил бы object.

Если тип value некорректен, возвращается ошибка.

napi_instanceof

Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_instanceof(napi_env env,
                            napi_value object,
                            napi_value constructor,
                            bool* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] object: JavaScript-значение, которое нужно проверить.
  • [in] constructor: JavaScript-объект функции конструктора, с которым нужно сравнить.
  • [out] result: Логическое значение, установленное в true, если object instanceof constructor равно true.

Возвращает napi_ok если API выполнилась успешно.

Этот API представляет вызов оператора instanceof над объектом, как определено в разделе 12.10.4 спецификации языка ECMAScript.

napi_is_array

Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_is_array(napi_env env, napi_value value, bool* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: JavaScript-значение, которое нужно проверить.
  • [out] result: Является ли данный объект массивом.

Возвращает napi_ok если API выполнилась успешно.

Этот API представляет вызов операции IsArray над объектом, как определено в разделе 7.2.2 спецификации языка ECMAScript.

napi_is_arraybuffer

Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_is_arraybuffer(napi_env env, napi_value value, bool* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: JavaScript-значение, которое нужно проверить.
  • [out] result: Является ли данный объект буфером.

Возвращает napi_ok если API выполнилась успешно.

Этот API проверяет, является ли переданный Object буфером.

napi_is_buffer

Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_is_buffer(napi_env env, napi_value value, bool* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: JavaScript-значение, которое нужно проверить.
  • [out] result: Представляет ли данное napi_value объект буфера.

Возвращает napi_ok если API выполнилась успешно.

Этот API проверяет, является ли переданное Object буфером.

napi_is_date

Добавлена в: v11.11.0, v10.17.0 Версия N-API: 5
napi_status napi_is_date(napi_env env, napi_value value, bool* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: JavaScript-значение, которое нужно проверить.
  • [out] result: Является ли данный объект JavaScript объектом даты.

Возвращает napi_ok если API выполнилась успешно.

Этот API проверяет, является ли переданное Object датой.

napi_is_error

Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_is_error(napi_env env, napi_value value, bool* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: JavaScript-значение, которое нужно проверить.
  • [out] result: Является ли данный объект объектом ошибки.

Возвращает napi_ok если API выполнилась успешно.

Этот API проверяет, является ли переданное Object ошибкой.

napi_is_typedarray

Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_is_typedarray(napi_env env, napi_value value, bool* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: JavaScript-значение, которое нужно проверить.
  • [out] result: Является ли данный объект массивом с типом.

Возвращает napi_ok если API выполнилась успешно.

Этот API проверяет, является ли переданное Object массивом с типом.

napi_is_dataview

Добавлена в: v8.3.0 Версия N-API: 1
napi_status napi_is_dataview(napi_env env, napi_value value, bool* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] value: JavaScript-значение, которое нужно проверить.
  • [out] result: Является ли данный объект объектом типа данных.

Возвращает napi_ok если API выполнилась успешно.

Этот API проверяет, является ли переданное Object объектом типа данных.

napi_strict_equals

Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_strict_equals(napi_env env,
                               napi_value lhs,
                               napi_value rhs,
                               bool* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] lhs: JavaScript-значение для проверки.
  • [in] rhs: JavaScript-значение для сравнения.
  • [out] result: Являются ли два объекта равными.

Возвращает napi_ok если API выполнилась успешно.

Этот API представляет вызов алгоритма строгого равенства, как определено в разделе 7.2.14 спецификации языка ECMAScript.

napi_detach_arraybuffer

Добавлена в: v13.0.0, v12.16.0, v10.22.0 Версия N-API: 7
napi_status napi_detach_arraybuffer(napi_env env,
                                    napi_value arraybuffer) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] arraybuffer: JavaScript-буфер, который необходимо отсоединить.

Возвращает napi_ok если API выполнилась успешно. Если передан неотсоединяемый буфер, возвращает napi_detachable_arraybuffer_expected.

END_OF_DOCUMENT_MARKER

Как правило, ArrayBuffer считается неотсоединяемым, если он был отсоединен ранее. Двигатель может накладывать дополнительные условия на возможность отсоединения ArrayBuffer. Например, V8 требует, чтобы ArrayBuffer был внешним, то есть созданным с помощью napi_create_external_arraybuffer.

Этот API представляет вызов операции отсоединения ArrayBuffer в соответствии со разделом 24.1.1.3 спецификации языка ECMAScript.

napi_is_detached_arraybuffer

Добавлен в: v13.3.0, v12.16.0, v10.22.0 Версия N-API: 7
napi_status napi_is_detached_arraybuffer(napi_env env,
                                         napi_value arraybuffer,
                                         bool* result) copy
  • [in] env: Среда, в которой вызывается API.
  • [in] arraybuffer: JavaScript ArrayBuffer, который нужно проверить.
  • [out] result: Отсоединён ли arraybuffer.

Возвращает napi_ok в случае успешного выполнения API.

ArrayBuffer считается отсоединённым, если его внутренние данные null.

Этот API представляет вызов операции ArrayBuffer IsDetachedBuffer в соответствии со разделом 24.1.1.2 спецификации языка ECMAScript.

Работа с свойствами JavaScript

Node-API предоставляет набор API для получения и установки свойств объектов JavaScript. Некоторые из этих типов задокументированы в разделе 7 спецификации языка ECMAScript.

Свойства в JavaScript представлены как кортеж из ключа и значения. В Node-API все ключи свойств в основном могут быть представлены в одном из следующих форматов:

  • Именованные: простая строка UTF8
  • Индексированные по целочисленному значению: значение индекса, представленное как uint32_t
  • Значение JavaScript: в Node-API они представлены как napi_value. Это может быть napi_value , представляющая string, number или symbol.

Значения Node-API представлены типом napi_value. Любой вызов Node-API, требующий значения JavaScript, принимает napi_value. Однако, ответственность за то, чтобы napi_value был того типа JavaScript, который ожидается API, лежит на вызывающей стороне.

API, описанные в этом разделе, предоставляют простой интерфейс для получения и установки свойств произвольных объектов JavaScript, представленных как napi_value.

Например, рассмотрим следующий фрагмент кода JavaScript:

const obj = {};
obj.myProp = 123; copy

Аналогичный результат можно получить с помощью значений Node-API с помощью следующего фрагмента:

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; copy

Индексированные свойства можно установить аналогичным образом. Рассмотрим следующий фрагмент кода JavaScript:

const arr = [];
arr[123] = 'hello'; copy

Аналогичный результат можно получить с помощью значений Node-API с помощью следующего фрагмента:

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; copy

Свойства можно получить, используя API, описанные в этом разделе. Рассмотрим следующий фрагмент кода JavaScript:

const arr = [];
const value = arr[123]; copy

Следующее приблизительно соответствует аналогу в Node-API:

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; copy

Наконец, для повышения производительности можно определить несколько свойств на объекте. Рассмотрим следующий фрагмент JavaScript:

const obj = {};
Object.defineProperties(obj, {
  'foo': { value: 123, writable: true, configurable: true, enumerable: true },
  'bar': { value: 456, writable: true, configurable: true, enumerable: true },
}); copy

Следующее приблизительно соответствует аналогу в Node-API:

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; copy

Структуры

napi_property_attributes
История
Версия Изменения
v14.12.0

добавлены napi_default_method и napi_default_property.

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; copy

napi_property_attributes — это флаги, используемые для управления поведением свойств, установленных на объекте JavaScript. Помимо napi_static, они соответствуют атрибутам, перечисленным в разделе 6.1.7.1 спецификации языка ECMAScript. Они могут быть одним или несколькими из следующих битовых флагов:

  • napi_default: Явно не устанавливаются атрибуты свойства. По умолчанию свойство является только для чтения, не перечисляемым и не настраиваемым.
  • napi_writable: Свойство может быть изменено.
  • napi_enumerable: Свойство перечисляется.
  • napi_configurable: Свойство может быть настроено, как определено в разделе 6.1.7.1 спецификации языка ECMAScript.
  • napi_static: Свойство будет определено как статическое свойство класса, а не свойство экземпляра (по умолчанию). Используется только napi_define_class. Игнорируется napi_define_properties.
  • napi_default_method: Подобно методу в классе JS, свойство настраиваемое и изменяемое, но не перечисляемое.
  • napi_default_jsproperty: Подобно свойству, заданному присвоением в JavaScript, свойство изменяемое, перечисляемое и настраиваемое.
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; copy
  • utf8name: Необязательная строка, описывающая ключ свойства, закодированная в UTF8. Для свойства должен быть задан один из utf8name или name.
  • name: Необязательное napi_value, указывающее на строку или символ JavaScript, используемые в качестве ключа свойства. Для свойства должен быть задан один из utf8name или name.
  • value: Значение, получаемое при чтении свойства, если оно является свойством данных. Если это передано, установите getter, setter, method и data в NULL (так как эти члены не будут использоваться).
  • getter: Функция, вызываемая при чтении свойства. Если это передано, установите value и method в NULL (так как эти члены не будут использоваться). Эта функция вызывается неявно во время выполнения при обращении к свойству из кода JavaScript (или при чтении свойства с помощью вызова Node-API). napi_callback содержит дополнительные сведения.
  • setter: Функция, вызываемая при записи в свойство. Если это передано, установите value и method в NULL (так как эти члены не будут использоваться). Эта функция вызывается неявно во время выполнения при установке свойства из кода JavaScript (или при записи в свойство с помощью вызова Node-API). napi_callback содержит дополнительные сведения.
  • method: Установите это значение, чтобы сделать свойство value объекта описателя свойства функцией JavaScript, представленной как method. Если это передано, установите value, getter и setter в NULL (так как эти члены не будут использоваться). napi_callback содержит дополнительные сведения.
  • attributes: Атрибуты, связанные с конкретным свойством. См. napi_property_attributes.
  • data: Данные обратного вызова, переданные в method, getter и setter при вызове этой функции.

Функции

napi_get_property_names
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_property_names(napi_env env,
                                    napi_value object,
                                    napi_value* result); copy
  • [in] env: Среда, в которой вызывается вызов Node-API.
  • [in] object: Объект, из которого нужно получить свойства.
  • [out] result: napi_value , представляющий массив значений JavaScript, представляющих имена свойств объекта. API можно использовать для итерации по result с помощью napi_get_array_length и napi_get_element.

Возвращает napi_ok в случае успешного выполнения API.

Это API возвращает имена перечисляемых свойств object в виде массива строк. Свойства object с ключом в виде символа не будут включены.

napi_get_all_property_names
Добавлена в: v13.7.0, v12.17.0, v10.20.0 Версия N-API: 6
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); copy
  • [in] env: Среда, в которой вызывается вызов Node-API.
  • [in] object: Объект, из которого нужно получить свойства.
  • [in] key_mode: Включать ли свойства прототипов.
  • [in] key_filter: Какие свойства получать (перечисляемые/читаемые/изменяемые).
  • [in] key_conversion: Преобразовывать ли числовые ключи свойств в строки.
  • [out] result: napi_value , представляющий массив значений JavaScript, представляющих имена свойств объекта. napi_get_array_length и napi_get_element могут использоваться для итерации по result.

Возвращает napi_ok в случае успешного выполнения API.

Это API возвращает массив, содержащий имена доступных свойств этого объекта.

napi_set_property
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_set_property(napi_env env,
                              napi_value object,
                              napi_value key,
                              napi_value value); copy
  • [in] env: Среда, в которой вызывается вызов Node-API.
  • [in] object: Объект, на котором нужно установить свойство.
  • [in] key: Имя свойства для установки.
  • [in] value: Значение свойства.

Возвращает napi_ok в случае успешного выполнения API.

Это API устанавливает свойство на переданный Object.

napi_get_property
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_property(napi_env env,
                              napi_value object,
                              napi_value key,
                              napi_value* result); copy
  • [in] env: Среда, в которой вызывается вызов Node-API.
  • [in] object: Объект, из которого нужно получить свойство.
  • [in] key: Имя свойства для получения.
  • [out] result: Значение свойства.

Возвращает napi_ok в случае успешного выполнения API.

Это API получает запрашиваемое свойство из переданного Object.

napi_has_property
Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_has_property(napi_env env,
                              napi_value object,
                              napi_value key,
                              bool* result); copy
  • [in] env: Среда, в которой вызывается вызов Node-API.
  • [in] object: Объект для запроса.
  • [in] key: Имя свойства, существование которого нужно проверить.
  • [out] result: Существует ли свойство в объекте.

Возвращает napi_ok в случае успешного выполнения API.

Это API проверяет, обладает ли переданный Object свойством с указанным именем.

napi_delete_property
Добавлена в: v8.2.0 Версия N-API: 1
napi_status napi_delete_property(napi_env env,
                                 napi_value object,
                                 napi_value key,
                                 bool* result); copy
  • [in] env: Среда, в которой вызывается вызов Node-API.
  • [in] object: Объект для запроса.
  • [in] key: Имя свойства для удаления.
  • [out] result: Удаление свойства успешно или нет. result можно необязательно пропустить, передав NULL.

Возвращает napi_ok при успешном выполнении API.

Этот API пытается удалить собственную свойство key из object.

napi_has_own_property
Добавлен в: v8.2.0 Версия N-API: 1
napi_status napi_has_own_property(napi_env env,
                                  napi_value object,
                                  napi_value key,
                                  bool* result); copy
  • [in] env: Окружение, в котором вызывается вызов Node-API.
  • [in] object: Объект для проверки.
  • [in] key: Название собственного свойства, существование которого нужно проверить.
  • [out] result: Существует ли это собственное свойство в объекте или нет.

Возвращает napi_ok при успешном выполнении API.

Этот API проверяет, обладает ли переданный Object указанным именем собственным свойством. key должен быть string или symbol, в противном случае будет выброшено исключение. Node-API не будет выполнять никаких преобразований между типами данных.

napi_set_named_property
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_set_named_property(napi_env env,
                                    napi_value object,
                                    const char* utf8Name,
                                    napi_value value); copy
  • [in] env: Окружение, в котором вызывается вызов Node-API.
  • [in] object: Объект, к которому нужно добавить свойство.
  • [in] utf8Name: Имя свойства, которое нужно установить.
  • [in] value: Значение свойства.

Возвращает napi_ok при успешном выполнении API.

Этот метод эквивалентен вызову napi_set_property со строкой, преобразованной в napi_value из строки, переданной в качестве utf8Name.

napi_get_named_property
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_get_named_property(napi_env env,
                                    napi_value object,
                                    const char* utf8Name,
                                    napi_value* result); copy
  • [in] env: Окружение, в котором вызывается вызов Node-API.
  • [in] object: Объект, из которого нужно извлечь свойство.
  • [in] utf8Name: Имя свойства, которое нужно получить.
  • [out] result: Значение свойства.

Возвращает napi_ok при успешном выполнении API.

Этот метод эквивалентен вызову napi_get_property со строкой, преобразованной в napi_value из строки, переданной в качестве utf8Name.

napi_has_named_property
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_has_named_property(napi_env env,
                                    napi_value object,
                                    const char* utf8Name,
                                    bool* result); copy
  • [in] env: Окружение, в котором вызывается вызов Node-API.
  • [in] object: Объект для проверки.
  • [in] utf8Name: Имя свойства, существование которого нужно проверить.
  • [out] result: Существует ли свойство в объекте или нет.

Возвращает napi_ok при успешном выполнении API.

Этот метод эквивалентен вызову napi_has_property со строкой, преобразованной в napi_value из строки, переданной в качестве utf8Name.

napi_set_element
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_set_element(napi_env env,
                             napi_value object,
                             uint32_t index,
                             napi_value value); copy
  • [in] env: Окружение, в котором вызывается вызов Node-API.
  • [in] object: Объект, к которому нужно установить свойство.
  • [in] index: Индекс свойства, которое нужно установить.
  • [in] value: Значение свойства.

Возвращает napi_ok при успешном выполнении API.

Этот API устанавливает элемент в переданный Object.

napi_get_element
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_get_element(napi_env env,
                             napi_value object,
                             uint32_t index,
                             napi_value* result); copy
  • [in] env: Окружение, в котором вызывается вызов Node-API.
  • [in] object: Объект, из которого нужно извлечь свойство.
  • [in] index: Индекс свойства, которое нужно получить.
  • [out] result: Значение свойства.

Возвращает napi_ok при успешном выполнении API.

Этот API получает элемент по запрошенному индексу.

napi_has_element
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_has_element(napi_env env,
                             napi_value object,
                             uint32_t index,
                             bool* result); copy
  • [in] env: Окружение, в котором вызывается вызов Node-API.
  • [in] object: Объект для проверки.
  • [in] index: Индекс свойства, существование которого нужно проверить.
  • [out] result: Существует ли свойство в объекте или нет.

Возвращает napi_ok при успешном выполнении API.

Этот API возвращает, обладает ли переданный Object элементом по запрошенному индексу.

napi_delete_element
Добавлен в: v8.2.0 Версия N-API: 1
napi_status napi_delete_element(napi_env env,
                                napi_value object,
                                uint32_t index,
                                bool* result); copy
  • [in] env: Окружение, в котором вызывается вызов Node-API.
  • [in] object: Объект для удаления элемента.
  • [in] index: Индекс свойства, которое нужно удалить.
  • [out] result: Удалось ли удалить элемент или нет. result можно необязательно игнорировать, передав NULL.

Возвращает napi_ok при успешном выполнении API.

Этот API пытается удалить указанный index из object.

napi_define_properties
Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_define_properties(napi_env env,
                                   napi_value object,
                                   size_t property_count,
                                   const napi_property_descriptor* properties); copy
  • [in] env: Окружение, в котором вызывается вызов Node-API.
  • [in] object: Объект, свойства которого нужно получить.
  • [in] property_count: Количество элементов в массиве properties.
  • [in] properties: Массив описателей свойств.

Возвращает napi_ok при успешном выполнении API.

Этот метод позволяет эффективно определять несколько свойств данного объекта. Свойства определяются с помощью описателей свойств (см. napi_property_descriptor). Учитывая массив таких описателей свойств, этот API будет устанавливать свойства в объекте по одному за раз, как определено DefineOwnProperty() (описано в разделе 9.1.6 спецификации ECMA-262).

napi_object_freeze
Добавлен в: v14.14.0, v12.20.0 Версия N-API: 8
napi_status napi_object_freeze(napi_env env,
                               napi_value object); copy
  • [in] env: Окружение, в котором вызывается вызов Node-API.
  • [in] object: Объект, который нужно заморозить.

Возвращает napi_ok при успешном выполнении API.

Этот метод замораживает данный объект. Это предотвращает добавление новых свойств, удаление существующих, изменение перечисляемости, конфигурируемости или записываемости существующих свойств, а также изменение значений существующих свойств. Также предотвращается изменение прототипа объекта. Это описано в разделе 19.1.2.6 спецификации ECMA-262.

napi_object_seal
Добавлен в: v14.14.0, v12.20.0 Версия N-API: 8
napi_status napi_object_seal(napi_env env,
                             napi_value object); copy
  • [in] env: Окружение, в котором вызывается вызов Node-API.
  • [in] object: Объект, который нужно запечатать.

Возвращает napi_ok при успешном выполнении API.

Этот метод запечатывает данный объект. Это предотвращает добавление новых свойств и отмечает все существующие свойства как неконфигурируемые. Это описано в разделе 19.1.2.20 спецификации ECMA-262.

Работа с функциями JavaScript

Node-API предоставляет набор API, которые позволяют коду JavaScript вызывать нативные функции. Node-API, поддерживающие обращение к нативному коду, принимают в качестве обратного вызова функции, представленные типом napi_callback. Когда JavaScript VM вызывает нативный код, вызывается предоставленная функция napi_callback. API, документированные в этом разделе, позволяют функции обратного вызова выполнять следующие действия:

  • Получить информацию о контексте, в котором был вызван обратный вызов.
  • Получить аргументы, переданные в обратный вызов.
  • Возвратить значение napi_value из обратного вызова.

Кроме того, Node-API предоставляет набор функций, позволяющих вызывать функции JavaScript из нативного кода. Можно вызвать функцию как обычный вызов JavaScript-функции или как конструкторскую функцию.

Любые данные, отличные от NULL, которые передаются этому API через поле data элементов napi_property_descriptor, могут быть связаны с object и освобождены, когда object собирается сборщиком мусора, передав как object, так и данные функции napi_add_finalizer.

napi_call_function

Добавлена в: v8.0.0 Версия N-API: 1
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); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] recv: Значение this, переданное вызываемой функции.
  • [in] func: Представление napi_value функции JavaScript, которая должна быть вызвана.
  • [in] argc: Количество элементов в массиве argv.
  • [in] argv: Массив napi_values, представляющий значения JavaScript, переданные в качестве аргументов функции.
  • [out] result: Представление napi_value возвращаемого JavaScript-объекта.

Возвращает napi_ok при успешном выполнении API.

Этот метод позволяет вызвать объект JavaScript-функции из нативного дополнения. Это основной механизм вызова из нативного кода дополнения в JavaScript. Для специального случая вызова JavaScript после асинхронной операции см. napi_make_callback.

Пример использования может выглядеть следующим образом. Рассмотрим следующий фрагмент JavaScript:

function AddTwo(num) {
  return num + 2;
}
global.AddTwo = AddTwo; copy

Затем, вышеприведенную функцию можно вызвать из нативного дополнения с помощью следующего кода:

// 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; copy

napi_create_function

Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_create_function(napi_env env,
                                 const char* utf8name,
                                 size_t length,
                                 napi_callback cb,
                                 void* data,
                                 napi_value* result); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] utf8Name: Необязательное имя функции, закодированное в UTF8. Это отображается в JavaScript как свойство name нового объекта функции.
  • [in] length: Длина utf8name в байтах или NAPI_AUTO_LENGTH, если это строка с нулевым окончанием.
  • [in] cb: Нативная функция, которая должна быть вызвана при вызове этого объекта функции. napi_callback предоставляет больше деталей.
  • [in] data: Контекст данных, предоставленный пользователем. Он будет передан обратно в функцию при ее последующем вызове.
  • [out] result: Представление napi_value JavaScript-объекта функции.

Возвращает napi_ok при успешном выполнении API.

Этот API позволяет автору дополнения создавать объект функции в нативном коде. Это основной механизм вызова в нативный код дополнения из JavaScript.

Новое созданное свойство функции не отображается автоматически в скрипте после этого вызова. Вместо этого свойство должно быть явно установлено на любом объекте, видимом для JavaScript, чтобы функция была доступна из скрипта.

Чтобы экспортировать функцию как часть экспорта модуля дополнения, установите созданную функцию на объект экспорта. Пример модуля может выглядеть следующим образом:

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) copy

Учитывая вышеприведенный код, дополнение можно использовать из JavaScript следующим образом:

const myaddon = require('./addon');
myaddon.sayHello(); copy

Строка, переданная в require(), является именем целевого объекта в binding.gyp, ответственного за создание файла .node.

Любые данные, отличные от NULL, которые передаются в этот API через параметр data, могут быть связаны с результирующей функцией JavaScript (возвращаемой в параметре result) и освобождены при сборе мусора функции, передав как функцию JavaScript, так и данные функции napi_add_finalizer.

JavaScript-функции описаны в разделе 19.2 спецификации языка ECMAScript.

napi_get_cb_info

Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_get_cb_info(napi_env env,
                             napi_callback_info cbinfo,
                             size_t* argc,
                             napi_value* argv,
                             napi_value* thisArg,
                             void** data) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] cbinfo: Информация о обратном вызове, переданная в функцию обратного вызова.
  • [in-out] argc: Указывает длину массива argv и получает фактическое количество аргументов. argc может быть необязательно проигнорирован, передав NULL.
  • [out] argv: Массив C из napi_value для копирования аргументов. Если аргументов больше, чем указанное количество, копируются только запрошенное количество аргументов. Если предоставлено меньше аргументов, чем указано, остальная часть argv заполняется значениями napi_value, представляющими undefined. argv можно необязательно проигнорировать, передав NULL.
  • [out] thisArg: Получает аргумент JavaScript this вызова. thisArg необязательно можно проигнорировать, передав NULL.
  • [out] data: Получает указатель на данные для обратного вызова. data можно необязательно проигнорировать, передав NULL.

Возвращает napi_ok при успешном выполнении API.

Этот метод используется внутри функции обратного вызова для извлечения деталей вызова, таких как аргументы и указатель this из заданной информации о обратном вызове.

napi_get_new_target

Добавлена в: v8.6.0 Версия N-API: 1
napi_status napi_get_new_target(napi_env env,
                                napi_callback_info cbinfo,
                                napi_value* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] cbinfo: Информация о обратном вызове, переданная в функцию обратного вызова.
  • [out] result: new.target вызова конструктора.

Возвращает napi_ok при успешном выполнении API.

Этот API возвращает new.target вызова конструктора. Если текущий обратный вызов не является вызовом конструктора, результат равен NULL.

napi_new_instance

Добавлена в: v8.0.0 Версия N-API: 1
napi_status napi_new_instance(napi_env env,
                              napi_value cons,
                              size_t argc,
                              napi_value* argv,
                              napi_value* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] cons: Представление napi_value JavaScript-функции, которая должна быть вызвана в качестве конструктора.
  • [in] argc: Количество элементов в массиве argv.
  • [in] argv: Массив значений JavaScript как napi_value, представляющих аргументы конструктора. Если argc равно нулю, этот параметр можно опустить, передав NULL.
  • [out] result: Представление napi_value возвращаемого JavaScript-объекта, который в данном случае является созданным объектом.

Этот метод используется для создания нового JavaScript-значения с использованием заданного napi_value, представляющего конструктор объекта. Например, рассмотрите следующий фрагмент:

function MyObject(param) {
  this.param = param;
}

const arg = 'hello';
const value = new MyObject(arg); copy

Следующее можно приблизить в Node-API с помощью следующего фрагмента:

// 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); copy

Возвращает napi_ok при успешном выполнении API.

Обертка объекта

Node-API предоставляет способ "обернуть" классы и экземпляры C++ так, чтобы конструктор класса и методы могли вызываться из JavaScript.

  1. API napi_define_class определяет JavaScript-класс с конструктором, статическими свойствами и методами, а также свойствами и методами экземпляров, соответствующими классу C++.
  2. Когда JavaScript-код вызывает конструктор, обратный вызов конструктора использует napi_wrap для обертывания нового экземпляра C++ в JavaScript-объект, затем возвращает обернутый объект.
  3. Когда JavaScript-код вызывает метод или аксессор свойства класса, вызывается соответствующая napi_callback функция C++. Для обратного вызова экземпляра napi_unwrap получает экземпляр C++, являющийся объектом вызова.

Для обернутых объектов может быть трудно отличить функцию, вызванную на прототипе класса, от функции, вызванной на экземпляре класса. Общим шаблоном для решения этой проблемы является сохранение постоянной ссылки на конструктор класса для последующих instanceof проверок.

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...
} copy

Ссылка должна быть освобождена, когда она больше не требуется.

Иногда napi_instanceof() недостаточно для обеспечения того, что JavaScript-объект является оберткой для определенного встроенного типа. Это особенно актуально, когда обернутые JavaScript-объекты передаются обратно в плагин через статические методы, а не в качестве this значения методов прототипа. В таких случаях существует вероятность некорректного разбора объекта.

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
} copy

В приведённом выше примере myAddon.queryHasRecords() — метод, принимающий два аргумента. Первый — дескриптор базы данных, второй — дескриптор запроса. Внутренне он разворачивает первый аргумент и приводит полученный указатель к встроенному дескриптору базы данных. Затем он разворачивает второй аргумент и приводит полученный указатель к дескриптору запроса. Если аргументы переданы в неправильном порядке, приведение типов сработает, однако велика вероятность, что внутренняя операция базы данных завершится ошибкой или приведёт к недопустимому доступу к памяти.

Для обеспечения того, что указатель, извлечённый из первого аргумента, действительно является указателем на дескриптор базы данных, а аналогично указатель, извлечённый из второго аргумента, действительно является указателем на дескриптор запроса, реализация queryHasRecords() должна выполнить проверку типа. Сохранение конструктора JavaScript-класса, из которого был создан дескриптор базы данных, и конструктора, из которого был создан дескриптор запроса, в napi_ref может помочь, так как napi_instanceof() может затем использоваться для обеспечения того, что экземпляры, переданные в queryHashRecords() , действительно имеют правильный тип.

К сожалению, napi_instanceof() не защищает от изменения прототипа. Например, прототип экземпляра дескриптора базы данных может быть установлен в прототип конструктора экземпляров дескриптора запроса. В этом случае экземпляр дескриптора базы данных может отображаться как экземпляр дескриптора запроса, и он пройдёт napi_instanceof() проверку на соответствие экземпляру дескриптора запроса, всё ещё содержа в себе указатель на дескриптор базы данных.

Для этого Node-API предоставляет возможности маркировки типов.

Тег типа — 128-битовое целое число, уникальное для плагина. Node-API предоставляет структуру napi_type_tag для хранения тега типа. Когда такое значение передаётся вместе с JavaScript-объектом или внешним значением, хранящимся в napi_value для napi_type_tag_object(), JavaScript-объект будет "помечен" тегом типа. "Пометка" невидима со стороны JavaScript. Когда JavaScript-объект поступает в встроенное связывание, napi_check_object_type_tag() может использоваться вместе с исходным тегом типа для определения, был ли JavaScript-объект ранее "помечен" тегом типа. Это создаёт возможность проверки типа с большей точностью, чем может предоставить napi_instanceof(), так как такая маркировка типа сохраняется при изменении прототипа и при загрузке/разгрузке плагина.

Продолжая приведенный выше пример, следующий скелетный код плагина демонстрирует использование napi_type_tag_object() и 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;
  }
} copy

napi_define_class

Добавлен в: v8.0.0 Версия N-API: 1
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); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] utf8name: Название JavaScript-функции-конструктора. Для ясности рекомендуется использовать имя C++-класса при обертывании C++-класса.
  • [in] length: Длина utf8name в байтах или NAPI_AUTO_LENGTH если она имеет нуль-терминатор.
  • [in] constructor: Функция обратного вызова, которая обрабатывает создание экземпляров класса. При обертывании C++-класса этот метод должен быть статическим членом с сигнатурой napi_callback. Нельзя использовать конструктор C++-класса. napi_callback содержит более подробную информацию.
  • [in] data: Дополнительные данные, передаваемые в обратный вызов конструктора как свойство data callback info.
  • [in] property_count: Количество элементов в массиве аргументов properties.
  • [in] properties: Массив описателей свойств, описывающих статические и экземплярные данные, аксессоры и методы класса. См. napi_property_descriptor.
  • [out] result: napi_value представляющий функцию-конструктор для класса.

Возвращает napi_ok в случае успеха API.

Определяет JavaScript-класс, включая:

  • JavaScript-функцию-конструктор, имеющую имя класса. При обертывании соответствующего C++-класса, обратный вызов, переданный через constructor , может быть использован для создания нового экземпляра C++-класса, который затем может быть помещен внутри создаваемого JavaScript-объекта-экземпляра с помощью napi_wrap.
  • Свойства функции-конструктора, реализация которых может вызывать соответствующие статические данные, аксессоры и методы C++-класса (определенные описателями свойств с атрибутом napi_static).
  • Свойства объекта прототипа функции-конструктора. При обертывании C++-класса, нестатические данные, аксессоры и методы C++-класса могут вызываться из статических функций, указанных в описателях свойств без атрибута napi_static после извлечения экземпляра C++-класса, помещённого внутрь JavaScript-объекта-экземпляра, с помощью napi_unwrap.

При обертывании C++-класса обратный вызов C++-конструктора, переданный через constructor , должен быть статическим методом класса, который вызывает фактический конструктор класса, затем оборачивает новый C++-экземпляр в JavaScript-объект и возвращает обернутый объект. Подробнее см. napi_wrap.

JavaScript-функция-конструктор, возвращённая из napi_define_class, часто сохраняется и используется позже для создания новых экземпляров класса из кода плагина и/или для проверки, являются ли предоставленные значения экземплярами класса. В этом случае, для предотвращения сборки мусора функции, можно создать сильную постоянную ссылку на неё с помощью napi_create_reference, гарантируя, что счётчик ссылок остаётся >= 1.

Любые не-NULL данные, передаваемые в этот API через параметр data или через поле data элементов массива napi_property_descriptor, могут быть связаны с полученным JavaScript-конструктором (который возвращается в параметре result) и освобождаться при сборе мусора класса, передав как JavaScript-функцию, так и данные в napi_add_finalizer.

napi_wrap

Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_wrap(napi_env env,
                      napi_value js_object,
                      void* native_object,
                      napi_finalize finalize_cb,
                      void* finalize_hint,
                      napi_ref* result); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] js_object: JavaScript-объект, который будет являться оберткой для встроенного объекта.
  • [in] native_object: Встроенный экземпляр, который будет обернут в JavaScript-объект.
  • [in] finalize_cb: Необязательный встроенный обратный вызов, который может быть использован для освобождения встроенного экземпляра, когда JavaScript-объект был собран мусором. napi_finalize содержит более подробную информацию.
  • [in] finalize_hint: Необязательный контекстный указатель, передаваемый в обратный вызов завершения.
  • [out] result: Необязательная ссылка на обернутый объект.

Возвращает napi_ok в случае успеха API.

Оборачивает встроенный экземпляр в JavaScript-объект. Встроенный экземпляр можно получить позже с помощью napi_unwrap().

Когда JavaScript-код вызывает конструктор класса, определённого с помощью napi_define_class(), вызывается napi_callback для конструктора. После создания экземпляра встроенного класса, обратный вызов должен вызвать napi_wrap() для обертывания вновь созданного экземпляра в уже созданный JavaScript-объект, который является this аргументом обратного вызова конструктора. (Этот this объект был создан из прототипа функции-конструктора, поэтому у него уже есть определения всех свойств и методов экземпляра.)

Обычно при обертывании экземпляра класса следует предоставить обратный вызов завершения, который просто удаляет встроенный экземпляр, полученный как data аргумент обратного вызова завершения.

Необязательная возвращённая ссылка изначально является слабой ссылкой, то есть имеет счётчик ссылок 0. Обычно этот счётчик ссылок временно увеличивается во время асинхронных операций, которые требуют, чтобы экземпляр оставался валидным.

Предупреждение: Необязательная возвращённая ссылка (если получена) должна быть удалена через napi_delete_reference ТОЛЬКО в ответ на вызов обратного вызова завершения. Если она удаляется до этого, то обратный вызов завершения может никогда не быть вызван. Поэтому при получении ссылки также необходим обратный вызов завершения для правильного удаления ссылки.

Обратные вызовы завершения могут быть отложены, оставляя окно, в котором объект был собран мусором (и слабая ссылка недействительна), но обратный вызов завершения ещё не был вызван. При использовании napi_get_reference_value() на слабых ссылках, возвращённых napi_wrap(), вы всё равно должны обрабатывать пустой результат.

Вызов napi_wrap() второй раз для объекта вернёт ошибку. Чтобы связать другой встроенный экземпляр с объектом, сначала используйте napi_remove_wrap().

napi_unwrap

Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_unwrap(napi_env env,
                        napi_value js_object,
                        void** result); copy
  • Окружение, в котором вызывается API.
  • Объект, связанный с нативным экземпляром.
  • Указатель на обернутый нативный экземпляр.

Возвращает результат успешного выполнения API.

Извлекает нативный экземпляр, который ранее был обернут в JavaScript-объект с помощью napi_wrap().

Когда JavaScript-код вызывает метод или обработчик доступа к свойству класса, вызывается соответствующий napi_callback. Если обратный вызов предназначен для метода или обработчика доступа к свойству экземпляра, то аргумент this обратного вызова — это обернутый объект; обернутый экземпляр C++ в качестве целевого объекта вызова можно получить, вызвав napi_unwrap() на объекте-обёртке.

napi_remove_wrap

Добавлен в: v8.5.0 Версия N-API: 1
napi_status napi_remove_wrap(napi_env env,
                             napi_value js_object,
                             void** result); copy
  • Окружение, в котором вызывается API.
  • Объект, связанный с нативным экземпляром.
  • Указатель на обернутый нативный экземпляр.

Возвращает результат успешного выполнения API.

Извлекает нативный экземпляр, который ранее был обернут в JavaScript-объект js_object с помощью napi_wrap() и удаляет оболочку. Если был связан обратный вызов для завершения, он больше не будет вызываться при сборе мусора JavaScript-объекта.

napi_type_tag_object

Добавлен в: v14.8.0, v12.19.0 Версия N-API: 8
napi_status napi_type_tag_object(napi_env env,
                                 napi_value js_object,
                                 const napi_type_tag* type_tag); copy
  • Окружение, в котором вызывается API.
  • JavaScript-объект или external, который следует пометить.
  • Тег, с помощью которого объект должен быть помечен.

Возвращает результат успешного выполнения API.

Связывает значение указателя type_tag с JavaScript-объектом или external. napi_check_object_type_tag() затем может использоваться для сравнения тега, прикреплённого к объекту, с тегом, принадлежащим дополнению, чтобы убедиться, что объект имеет нужный тип.

Если у объекта уже есть связанный тег типа, этот API вернёт napi_invalid_arg.

napi_check_object_type_tag

Добавлен в: v14.8.0, v12.19.0 Версия N-API: 8
napi_status napi_check_object_type_tag(napi_env env,
                                       napi_value js_object,
                                       const napi_type_tag* type_tag,
                                       bool* result); copy
  • Окружение, в котором вызывается API.
  • JavaScript-объект или external, тег типа которого следует проверить.
  • Тег для сравнения с любым найденным тегом объекта.
  • Соответствует ли предоставленный тег типа тегу типа объекта. false также возвращается, если на объекте не найден ни один тег типа.

Возвращает результат успешного выполнения API.

Сравнивает указанный в качестве type_tag указатель с любым указателем, который может быть найден на js_object. Если на js_object не найден ни один тег или если найден тег, но он не совпадает с type_tag, result устанавливается в false. Если тег найден и совпадает с type_tag, result устанавливается в true.

napi_add_finalizer

Добавлен в: v8.0.0 Версия N-API: 5
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); copy
  • Окружение, в котором вызывается API.
  • JavaScript-объект, к которому будет прикреплены нативные данные.
  • Дополнительные данные, которые будут переданы в finalize_cb.
  • Нативный обратный вызов, который будет использован для освобождения нативных данных при сборе мусора JavaScript-объекта. napi_finalize предоставляет больше деталей.
  • Дополнительный контекстный подсказка, передаваемый в обратный вызов завершения.
  • Необязательная ссылка на JavaScript-объект.

Возвращает результат успешного выполнения API.

Добавляет обратный вызов napi_finalize, который будет вызываться при сборе мусора JavaScript-объекта в js_object.

Этот API может быть вызван несколько раз для одного JavaScript-объекта.

Предупреждение: Необязательная возвращённая ссылка (если получена) должна быть удалена с помощью napi_delete_reference ТОЛЬКО в ответ на вызов обратного вызова завершения. Если она удалена до этого момента, то обратный вызов завершения может никогда не быть вызван. Поэтому при получении ссылки также требуется обратный вызов завершения для правильного удаления ссылки.

Простые асинхронные операции

Модули-надстройки часто нуждаются в использовании асинхронных помощников из libuv в рамках своей реализации. Это позволяет им планировать выполнение работы асинхронно, чтобы их методы могли возвращаться до завершения работы. Это позволяет избежать блокировки общей работы приложения Node.js.

Node-API предоставляет стабильный по ABI интерфейс для этих вспомогательных функций, охватывающий наиболее распространенные случаи асинхронного использования.

Node-API определяет структуру napi_async_work, которая используется для управления асинхронными рабочими процессами. Экземпляры создаются/удаляются с помощью napi_create_async_work и napi_delete_async_work.

Обратные вызовы execute и complete — это функции, которые будут вызваны, когда исполнитель готов к выполнению и когда он завершит свою задачу соответственно.

Функция execute должна избегать выполнения каких-либо вызовов Node-API, которые могут привести к выполнению JavaScript или взаимодействию с объектами JavaScript. Чаще всего любой код, которому необходимо выполнить вызовы Node-API, должен выполняться в обратном вызове complete вместо этого. Избегайте использования параметра napi_env в обратном вызове выполнения, так как он, вероятно, выполнит JavaScript.

Эти функции реализуют следующие интерфейсы:

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); copy

При вызове этих методов переданный параметр data будет содержать предоставленные надстройкой данные void*, которые были переданы в вызов napi_create_async_work.

После создания асинхронный рабочий процесс можно поставить в очередь на выполнение с помощью функции napi_queue_async_work:

napi_status napi_queue_async_work(napi_env env,
                                  napi_async_work work); copy

napi_cancel_async_work может быть использована, если работу необходимо отменить до начала выполнения.

После вызова napi_cancel_async_work, обратный вызов complete будет вызван со значением состояния napi_cancelled. Работа не должна быть удалена до вызова обратного вызова complete, даже если она была отменена.

napi_create_async_work

История
Версия Изменения
v8.6.0

Добавлены параметры async_resource и async_resource_name.

v8.0.0

Добавлен в: v8.0.0

Версия N-API: 1
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); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] async_resource: Необязательный объект, связанный с асинхронной работой, который будет передан возможным async_hooks init обработчикам.
  • [in] async_resource_name: Идентификатор типа ресурса, предоставляемый для диагностической информации, экспонируемой API async_hooks.
  • [in] execute: Функция нативного кода, которая должна вызываться для выполнения логики асинхронно. Данная функция вызывается из потока пула рабочих процессов и может выполняться параллельно с основным потоком событий.
  • [in] complete: Функция нативного кода, которая будет вызвана при завершении или отмене асинхронной логики. Данная функция вызывается из основного потока событий. napi_async_complete_callback предоставляет более подробные сведения.
  • [in] data: Контекст данных, предоставленный пользователем. Он будет возвращен в функции выполнения и завершения.
  • [out] result: napi_async_work*, который является дескриптором только что созданной асинхронной работы.

Возвращает napi_ok в случае успешного выполнения API.

Этот API выделяет объект работы, используемый для асинхронного выполнения логики. Он должен быть освобожден с помощью napi_delete_async_work, как только работа больше не потребуется.

async_resource_name должен быть строкой UTF-8, завершаемой нулем.

Идентификатор async_resource_name предоставляется пользователем и должен отражать тип выполняемой асинхронной работы. Также рекомендуется применять именование к идентификатору, например, включив в него имя модуля. Дополнительная информация приведена в документации async_hooks.

napi_delete_async_work

Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_delete_async_work(napi_env env,
                                   napi_async_work work); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] work: Дескриптор, возвращенный вызовом napi_create_async_work.

Возвращает napi_ok в случае успешного выполнения API.

Этот API освобождает ранее выделенный объект работы.

Этот API может быть вызван даже при наличии ожидающего исключения JavaScript.

napi_queue_async_work

Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_queue_async_work(napi_env env,
                                  napi_async_work work); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] work: Дескриптор, возвращенный вызовом napi_create_async_work.

Возвращает napi_ok в случае успешного выполнения API.

Этот API запрашивает планирование ранее выделенной работы для выполнения. После успешного возврата этот API не должен вызываться повторно с тем же элементом napi_async_work, иначе результат будет неопределенным.

napi_cancel_async_work

Добавлен в: v8.0.0 Версия N-API: 1
napi_status napi_cancel_async_work(napi_env env,
                                   napi_async_work work); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] work: Дескриптор, возвращенный вызовом napi_create_async_work.

Возвращает napi_ok в случае успешного выполнения API.

Этот API отменяет запланированную работу, если она еще не началась. Если она уже начала выполняться, ее нельзя отменить, и будет возвращено значение napi_generic_failure. В случае успеха обратный вызов complete будет вызван со значением статуса napi_cancelled. Работа не должна быть удалена до вызова обратного вызова complete, даже если она была успешно отменена.

Этот API может быть вызван даже при наличии ожидающего исключения JavaScript.

Настраиваемые асинхронные операции

Простые асинхронные API выше могут быть неподходящими для всех сценариев. При использовании других асинхронных механизмов следующие API необходимы, чтобы гарантировать, что асинхронная операция корректно отслеживается во время выполнения.

napi_async_init

Добавлен в: v8.6.0Версия N-API: 1
napi_status napi_async_init(napi_env env,
                            napi_value async_resource,
                            napi_value async_resource_name,
                            napi_async_context* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] async_resource: Объект, связанный с асинхронной работой, который будет передан возможным async_hooks init хукам и к которому можно получить доступ с помощью async_hooks.executionAsyncResource().
  • [in] async_resource_name: Идентификатор типа ресурса, предоставляемого для диагностической информации, экспонируемой API async_hooks.
  • [out] result: Инициализированный асинхронный контекст.

Возвращает napi_ok в случае успешного выполнения API.

Объект async_resource необходимо сохранить до вызова napi_async_destroy, чтобы API, связанные с async_hooks, работали корректно. Для сохранения совместимости с предыдущими версиями, API не сохраняют сильную ссылку на объекты async_resource, чтобы избежать утечки памяти. Однако, если объект async_resource будет собран сборщиком мусора JavaScript до того, как napi_async_context будет уничтожен napi_async_destroy, вызов связанных с napi_async_context API, таких как napi_open_callback_scope и napi_make_callback, может привести к проблемам, таким как потеря асинхронного контекста при использовании API AsyncLocalStorage.

Для сохранения совместимости с предыдущими версиями передача NULL в качестве async_resource не приводит к ошибке. Однако это не рекомендуется, так как это может привести к плохим результатам с async_hooks init хуками и async_hooks.executionAsyncResource(), так как ресурс теперь необходим для реализации async_hooks подсистемы, чтобы обеспечить связь между асинхронными обратными вызовами.

napi_async_destroy

Добавлен в: v8.6.0Версия N-API: 1
napi_status napi_async_destroy(napi_env env,
                               napi_async_context async_context); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] async_context: Асинхронный контекст, который необходимо уничтожить.

Возвращает napi_ok в случае успешного выполнения API.

Этот API можно вызывать даже при наличии ожидающей JavaScript-исключительной ситуации.

napi_make_callback

История
ВерсияИзменения
v8.6.0

Добавлен параметр async_context.

v8.0.0

Добавлен в: v8.0.0

Версия N-API: 1
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); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] async_context: Контекст асинхронной операции, вызывающей обратный вызов. Обычно это значение, полученное ранее из napi_async_init. Для сохранения совместимости с предыдущими версиями, передача NULL в качестве async_context не приводит к ошибке. Однако это приводит к неправильной работе асинхронных хуков. Возможные проблемы включают потерю асинхронного контекста при использовании API AsyncLocalStorage.
  • [in] recv: Значение this, переданное вызываемой функции.
  • [in] func: Значение napi_value, представляющее вызываемую JavaScript-функцию.
  • [in] argc: Количество элементов в массиве argv.
  • [in] argv: Массив JavaScript-значений как napi_value, представляющий аргументы функции. Если argc равно нулю, этот параметр можно опустить, передав NULL.
  • [out] result: Значение napi_value, представляющее возвращаемый JavaScript-объект.

Возвращает napi_ok в случае успешного выполнения API.

Этот метод позволяет вызывать JavaScript-функцию из нативного дополнения. Этот API похож на napi_call_function. Однако он используется для вызова из нативного кода обратно в JavaScript после возврата из асинхронной операции (когда в стеке нет другого скрипта). Это довольно простой оболочка вокруг node::MakeCallback.

Обратите внимание, что использование napi_make_callback не обязательно внутри napi_async_complete_callback; в этой ситуации асинхронный контекст обратного вызова уже настроен, поэтому прямой вызов napi_call_function достаточен и уместен. Функция napi_make_callback может потребоваться при реализации пользовательского асинхронного поведения, которое не использует napi_create_async_work.

Любые process.nextTick или промисы, запланированные в очереди микрозадач JavaScript во время обратного вызова, выполняются перед возвратом в C/C++.

napi_open_callback_scope

Добавлен в: v9.6.0Версия N-API: 3
NAPI_EXTERN napi_status napi_open_callback_scope(napi_env env,
                                                 napi_value resource_object,
                                                 napi_async_context context,
                                                 napi_callback_scope* result) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] resource_object: Объект, связанный с асинхронной работой, который будет передан возможным async_hooks init хукам. Этот параметр устарел и игнорируется во время выполнения. Используйте параметр async_resource в napi_async_init вместо него.
  • [in] context: Контекст асинхронной операции, вызывающей обратный вызов. Это должно быть значение, полученное ранее из napi_async_init.
  • [out] result: Созданный контекст.

В некоторых случаях (например, при разрешении промисов) необходимо иметь эквивалент контекста, связанного с обратным вызовом, когда выполняются определенные вызовы Node-API. Если в стеке нет других скриптов, функции napi_open_callback_scope и napi_close_callback_scope могут использоваться для открытия/закрытия необходимого контекста.

napi_close_callback_scope

Добавлен в: v9.6.0Версия N-API: 3
NAPI_EXTERN napi_status napi_close_callback_scope(napi_env env,
                                                  napi_callback_scope scope) copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] scope: Контекст, который нужно закрыть.

Этот API можно вызывать даже при наличии ожидающей JavaScript-исключительной ситуации.

Управление версиями

napi_get_node_version

Добавлен в: v8.4.0Версия N-API: 1
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); copy
  • [in] env: Окружение, в котором вызывается API.
  • [out] version: Указатель на информацию о версии самого Node.js.

Возвращает napi_ok в случае успешного выполнения API.

Эта функция заполняет структуру version значениями основной, дополнительной и поправочной версий Node.js, а также значением поля release с помощью process.release.name.

Возвращаемый буфер статически выделяется и не требует освобождения.

napi_get_version

Добавлен в: v8.0.0Версия N-API: 1
napi_status napi_get_version(napi_env env,
                             uint32_t* result); copy
  • [in] env: Окружение, в котором вызывается API.
  • [out] result: Самая высокая поддерживаемая версия Node-API.

Возвращает napi_ok в случае успешного выполнения API.

Этот API возвращает самую высокую поддерживаемую версию Node-API в среде выполнения Node.js. Node-API планируется как добавление, так что более новые версии Node.js могут поддерживать дополнительные функции API. Чтобы предоставить дополнению возможность использовать новую функцию при работе с версиями Node.js, которые ее поддерживают, а также обеспечивая поведение по умолчанию для версий, которые не поддерживают эту функцию:

  • Вызовите napi_get_version() для определения доступности API.
  • Если доступно, динамически загрузите указатель на функцию с помощью uv_dlsym().
  • Используйте загруженный указатель для вызова функции.
  • Если функция недоступна, предоставьте альтернативную реализацию, которая не использует эту функцию.

Управление памятью

napi_adjust_external_memory

Добавлен в: v8.5.0Версия N-API: 1
NAPI_EXTERN napi_status napi_adjust_external_memory(napi_env env,
                                                    int64_t change_in_bytes,
                                                    int64_t* result); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] change_in_bytes: Изменение внешней памяти, которая поддерживается JavaScript-объектами.
  • [out] result: Скорректированное значение.

Возвращает napi_ok в случае успешного выполнения API.

Эта функция предоставляет V8 указание на объем внешней памяти, поддерживаемой JavaScript-объектами (т. е. JavaScript-объект, который указывает на свою собственную память, выделенную нативным дополнением). Регистрация внешней памяти вызовет глобальные сборки мусора чаще, чем это было бы в противном случае.

END_OF_DOCUMENT_MARKER

Обещания

Node-API предоставляет средства для создания Promise объектов, как описано в разделе 25.4 спецификации ECMA. Он реализует обещания как пару объектов. При создании обещания функцией napi_create_promise(), создаётся объект "отложенного выполнения" и возвращается вместе с Promise. Объект отложенного выполнения связан с созданным Promise и является единственным способом разрешить или отклонить Promise с помощью napi_resolve_deferred() или napi_reject_deferred(). Объект отложенного выполнения, созданный функцией napi_create_promise(), освобождается функциями napi_resolve_deferred() или napi_reject_deferred(). Объект Promise может быть возвращен в JavaScript, где он может использоваться обычным способом.

Например, для создания обещания и передачи его асинхронному рабочему процессу:

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; copy

Функция do_something_asynchronous() выполнит своё асинхронное действие, а затем разрешит или отклонит отложенное выполнение, тем самым завершая обещание и освобождая отложенное выполнение:

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; copy

napi_create_promise

Добавлен в: v8.5.0 Версия N-API: 1
napi_status napi_create_promise(napi_env env,
                                napi_deferred* deferred,
                                napi_value* promise); copy
  • [in] env: Окружение, в котором вызывается API.
  • [out] deferred: Новый созданный объект отложенного выполнения, который позже можно передать функциям napi_resolve_deferred() или napi_reject_deferred() для разрешения, соответственно, отклонения связанного обещания.
  • [out] promise: JavaScript-обещание, связанное с объектом отложенного выполнения.

Возвращает napi_ok в случае успешного выполнения API.

Этот API создаёт объект отложенного выполнения и JavaScript-обещание.

napi_resolve_deferred

Добавлен в: v8.5.0 Версия N-API: 1
napi_status napi_resolve_deferred(napi_env env,
                                  napi_deferred deferred,
                                  napi_value resolution); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] deferred: Объект отложенного выполнения, связанное обещание которого требуется разрешить.
  • [in] resolution: Значение, с помощью которого разрешить обещание.

Этот API разрешает JavaScript-обещание с помощью связанного с ним объекта отложенного выполнения. Таким образом, он может использоваться только для разрешения JavaScript-обещаний, для которых доступен соответствующий объект отложенного выполнения. Это означает, что обещание должно быть создано с помощью napi_create_promise() и объект отложенного выполнения, возвращённый этим вызовом, должен быть сохранён для передачи в этот API.

Объект отложенного выполнения освобождается при успешном завершении.

napi_reject_deferred

Добавлен в: v8.5.0 Версия N-API: 1
napi_status napi_reject_deferred(napi_env env,
                                 napi_deferred deferred,
                                 napi_value rejection); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] deferred: Объект отложенного выполнения, связанное обещание которого требуется отклонить.
  • [in] rejection: Значение, с помощью которого отклонить обещание.

Этот API отклоняет JavaScript-обещание с помощью связанного с ним объекта отложенного выполнения. Таким образом, он может использоваться только для отклонения JavaScript-обещаний, для которых доступен соответствующий объект отложенного выполнения. Это означает, что обещание должно быть создано с помощью napi_create_promise() и объект отложенного выполнения, возвращённый этим вызовом, должен быть сохранён для передачи в этот API.

Объект отложенного выполнения освобождается при успешном завершении.

napi_is_promise

Добавлен в: v8.5.0 Версия N-API: 1
napi_status napi_is_promise(napi_env env,
                            napi_value value,
                            bool* is_promise); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] value: Значение для проверки
  • [out] is_promise: Флаг, указывающий, является ли promise объектом нативного обещания (то есть, объектом обещания, созданным базовым движком).

Выполнение скрипта

Node-API предоставляет API для выполнения строки JavaScript-кода с использованием базового JavaScript-движка.

napi_run_script

Добавлен в: v8.5.0 Версия N-API: 1
NAPI_EXTERN napi_status napi_run_script(napi_env env,
                                        napi_value script,
                                        napi_value* result); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] script: Строка JavaScript, содержащая скрипт для выполнения.
  • [out] result: Результат выполнения скрипта.

Эта функция выполняет строку JavaScript-кода и возвращает её результат с последующими оговорками:

  • В отличие от eval, эта функция не позволяет скрипту получить доступ к текущей лексической области видимости, а следовательно, и не позволяет получить доступ к области видимости модуля, что означает, что псевдоглобальные переменные, такие как require, недоступны.
  • Скрипт может получить доступ к глобальной области видимости. Объявления функций и var в скрипте будут добавлены в объект global.
  • Объявления переменных, выполненные с помощью let и const, будут глобально видимы, но не будут добавлены в объект global.
  • Значение this в скрипте равно global.

Цикл событий libuv

Node-API предоставляет функцию для получения текущего цикла событий, связанного с определённым napi_env.

napi_get_uv_event_loop

Добавлен в: v9.3.0, v8.10.0 Версия N-API: 2
NAPI_EXTERN napi_status napi_get_uv_event_loop(napi_env env,
                                               struct uv_loop_s** loop); copy
  • [in] env: Окружение, в котором вызывается API.
  • [out] loop: Текущая инстанция цикла событий libuv.

Асинхронные потокобезопасные вызовы функций

Функции JavaScript обычно могут вызываться только из основного потока нативного плагина. Если плагин создаёт дополнительные потоки, то функции Node-API, требующие napi_env, napi_value, или napi_ref, не должны вызываться из этих потоков.

Когда у плагина есть дополнительные потоки, а функции JavaScript нужно вызывать на основе обработки, выполненной этими потоками, эти потоки должны взаимодействовать с основным потоком плагина, чтобы основной поток мог вызвать функцию JavaScript от их имени. Потокобезопасные API предоставляют лёгкий способ сделать это.

Эти API предоставляют тип napi_threadsafe_function , а также API для создания, уничтожения и вызова объектов этого типа. napi_create_threadsafe_function() создаёт постоянную ссылку на napi_value , содержащую функцию JavaScript, которую можно вызывать из нескольких потоков. Вызовы происходят асинхронно. Это означает, что значения, с которыми JavaScript-обработчик должен быть вызван, будут помещены в очередь, и для каждого значения в очереди в конечном итоге будет выполнен вызов функции JavaScript.

При создании napi_threadsafe_function может быть предоставлен обработчик napi_finalize. Этот обработчик будет вызван в основном потоке, когда потокобезопасная функция будет уничтожена. Он получает контекст и данные завершения, предоставленные во время создания, и предоставляет возможность очистки после потоков, например, вызывая uv_thread_join(). Помимо основного потока цикла, никакие потоки не должны использовать потокобезопасную функцию после завершения обработчика завершения.

context , предоставленное во время вызова napi_create_threadsafe_function(), может быть получено из любого потока с помощью вызова napi_get_threadsafe_function_context().

Вызов потокобезопасной функции

napi_call_threadsafe_function() может использоваться для инициирования вызова в JavaScript. napi_call_threadsafe_function() принимает параметр, который управляет поведением API — блокирующим или нет. Если он установлен в значение napi_tsfn_nonblocking, API работает без блокировки, возвращая napi_queue_full, если очередь была полной, предотвращая успешное добавление данных в очередь. Если он установлен в значение napi_tsfn_blocking, API блокируется до тех пор, пока в очереди не появится место. napi_call_threadsafe_function() никогда не блокируется, если потокобезопасная функция была создана с максимальным размером очереди 0.

napi_call_threadsafe_function() не следует вызывать со значением napi_tsfn_blocking из потока JavaScript, потому что, если очередь полна, это может привести к тупику в потоке JavaScript.

Фактический вызов в JavaScript контролируется обработчиком, переданным через параметр call_js_cb. call_js_cb вызывается в основном потоке один раз для каждого значения, помещённого в очередь успешным вызовом napi_call_threadsafe_function(). Если такой обработчик не задан, будет использоваться обработчик по умолчанию, и результирующий вызов JavaScript не будет иметь аргументов. Обработчик call_js_cb получает функцию JavaScript для вызова как napi_value в своих параметрах, а также указатель контекста void* , используемый при создании napi_threadsafe_function, и указатель на следующие данные, созданные одним из вторичных потоков. Затем обработчик может использовать API, такой как napi_call_function(), для вызова JavaScript.

Обработчик также может быть вызван со значениями env и call_js_cb , оба установленные в NULL, чтобы указать, что вызовы в JavaScript больше невозможны, в то время как в очереди остаются элементы, которые могут потребоваться освободить. Это обычно происходит при завершении процесса Node.js, когда активна потокобезопасная функция.

Не нужно вызывать JavaScript через napi_make_callback(), потому что Node-API выполняет call_js_cb в контексте, подходящем для обратных вызовов.

В каждом цикле обработки событий может быть вызвано ноль или более элементов очереди. Приложения не должны полагаться на определённое поведение, кроме того, что будут выполняться вызовы обратных функций и будут происходить события по мере продвижения времени.

Счётчик ссылок потокобезопасных функций

К объекту napi_threadsafe_function можно добавлять и удалять потоки в течение его существования. Таким образом, помимо указания начального числа потоков при создании, napi_acquire_threadsafe_function можно вызвать, чтобы указать, что новый поток начнёт использовать потокобезопасную функцию. Аналогично, napi_release_threadsafe_function можно вызвать, чтобы указать, что существующий поток перестанет использовать потокобезопасную функцию.

Объекты napi_threadsafe_function уничтожаются, когда каждый поток, использующий объект, вызвал napi_release_threadsafe_function() или получил статус возврата napi_closing в ответ на вызов napi_call_threadsafe_function. Очередь очищается перед уничтожением napi_threadsafe_function. napi_release_threadsafe_function() должен быть последним вызовом API, связанным с данной napi_threadsafe_function, потому что после завершения вызова нет гарантии, что napi_threadsafe_function всё ещё выделен. По той же причине не используйте потокобезопасную функцию после получения значения возврата napi_closing в ответ на вызов napi_call_threadsafe_function. Данные, связанные с napi_threadsafe_function, могут быть освобождены в его обработчике napi_finalize , переданном в napi_create_threadsafe_function(). Параметр initial_thread_count из napi_create_threadsafe_function обозначает начальное количество приобретений потокобезопасных функций вместо вызова napi_acquire_threadsafe_function несколько раз при создании.

После того, как количество потоков, использующих napi_threadsafe_function, достигнет нуля, больше нельзя начинать использовать его другие потоки, вызывая napi_acquire_threadsafe_function(). На самом деле, все последующие вызовы API, связанные с ним, за исключением napi_release_threadsafe_function(), вернут значение ошибки napi_closing.

Потокобезопасная функция может быть «прервана», присвоив значение napi_tsfn_abort функции napi_release_threadsafe_function(). Это заставит все последующие API, связанные с потокобезопасной функцией, за исключением napi_release_threadsafe_function(), возвращать napi_closing даже до того, как счётчик ссылок достигнет нуля. В частности, napi_call_threadsafe_function() вернёт napi_closing, таким образом сообщив потокам, что асинхронные вызовы потокобезопасной функции больше невозможны. Это можно использовать в качестве критерия для завершения потока. После получения значения возврата napi_closing от napi_call_threadsafe_function() поток больше не должен использовать потокобезопасную функцию, потому что она больше не гарантируется выделенной.

Решение о сохранении процесса запущенным

Аналогично обработчикам libuv, потокобезопасные функции могут быть «ссылочные» и «нессылочные». «Ссылочная» потокобезопасная функция заставит цикл обработки событий в потоке, в котором она создана, оставаться активным до тех пор, пока потокобезопасная функция не будет уничтожена. В отличие от этого, «нессылочная» потокобезопасная функция не помешает циклу обработки событий завершиться. Для этой цели существуют API napi_ref_threadsafe_function и napi_unref_threadsafe_function.

Ни napi_unref_threadsafe_function не помечает потокобезопасные функции как подлежащие уничтожению, ни napi_ref_threadsafe_function не предотвращает их уничтожения.

napi_create_threadsafe_function

История
Версия Изменения
v12.6.0, v10.17.0

Параметр func стал необязательным с настраиваемым call_js_cb.

v10.6.0

Добавлен: v10.6.0

Версия N-API: 4
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); copy
  • [in] env: Окружение, в котором вызывается API.
  • [in] func: Необязательная функция JavaScript для вызова из другого потока. Она должна быть предоставлена, если NULL передаётся в call_js_cb.
  • [in] async_resource: Необязательный объект, связанный с асинхронной работой, который будет передан возможным async_hooks init крючкам.
  • [in] async_resource_name: Строка JavaScript, предоставляющая идентификатор типа ресурса, предоставляемого для диагностической информации, экспонируемой API async_hooks.
  • [in] max_queue_size: Максимальный размер очереди. 0 для отсутствия лимита.
  • [in] initial_thread_count: Начальное количество приобретений, то есть начальное число потоков, включая основной поток, которые будут использовать эту функцию.
  • [in] thread_finalize_data: Необязательные данные для передачи в thread_finalize_cb.
  • [in] thread_finalize_cb: Необязательная функция, вызываемая при уничтожении napi_threadsafe_function.
  • [in] context: Необязательные данные для добавления к результатам napi_threadsafe_function.
  • [in] call_js_cb: Необязательный обратный вызов, вызывающий функцию JavaScript в ответ на вызов в другом потоке. Этот обратный вызов будет вызван в основном потоке. Если он не задан, функция JavaScript будет вызвана без параметров и с undefined в качестве значения this . napi_threadsafe_function_call_js содержит более подробные сведения.
  • [out] result: Асинхронная потокобезопасная функция JavaScript.

napi_get_threadsafe_function_context

Добавлен: v10.6.0 Версия N-API: 4
NAPI_EXTERN napi_status
napi_get_threadsafe_function_context(napi_threadsafe_function func,
                                     void** result); copy
  • [in] func: Потокобезопасная функция, для которой необходимо получить контекст.
  • [out] result: Место хранения контекста.

Этот API может вызываться из любого потока, использующего func.

napi_call_threadsafe_function

История
Версия Изменения
v14.5.0

Поддержка napi_would_deadlock отменена.

v14.1.0

Возвращается napi_would_deadlock при вызове со значением napi_tsfn_blocking из основного или рабочего потока, если очередь полна.

v10.6.0

Добавлен: v10.6.0

Версия N-API: 4
NAPI_EXTERN napi_status
napi_call_threadsafe_function(napi_threadsafe_function func,
                              void* data,
                              napi_threadsafe_function_call_mode is_blocking); copy
  • [in] func: Асинхронная потокобезопасная функция JavaScript для вызова.
  • [in] data: Данные, которые нужно передать в JavaScript через обратный вызов call_js_cb при создании потокобезопасной функции JavaScript.
  • [in] is_blocking: Флаг, значение которого может быть napi_tsfn_blocking для указания того, что вызов должен заблокироваться, если очередь заполнена, или napi_tsfn_nonblocking для указания того, что вызов должен возвратиться немедленно со статусом napi_queue_full всякий раз, когда очередь заполнена.

Этот API не следует вызывать с napi_tsfn_blocking из потока JavaScript, потому что, если очередь заполнена, это может привести к зависанию потока JavaScript.

Этот API вернёт napi_closing если napi_release_threadsafe_function() был вызван с abort установленным в napi_tsfn_abort из любого потока. Значение добавляется в очередь только если API возвращает napi_ok.

Этот API может вызываться из любого потока, использующего func.

napi_acquire_threadsafe_function

Добавлен в: v10.6.0 Версия N-API: 4
NAPI_EXTERN napi_status
napi_acquire_threadsafe_function(napi_threadsafe_function func); copy
  • [in] func: Асинхронная потокобезопасная функция JavaScript, использование которой необходимо начать.

Поток должен вызвать этот API перед передачей func другим потокобезопасным функциям API, чтобы указать, что он будет использовать func. Это предотвращает уничтожение func когда все другие потоки прекратят использование.

Этот API может вызываться из любого потока, который начнёт использовать func.

napi_release_threadsafe_function

Добавлен в: v10.6.0 Версия N-API: 4
NAPI_EXTERN napi_status
napi_release_threadsafe_function(napi_threadsafe_function func,
                                 napi_threadsafe_function_release_mode mode); copy
  • [in] func: Асинхронная потокобезопасная функция JavaScript, счётчик ссылок которой нужно уменьшить.
  • [in] mode: Флаг, значение которого может быть napi_tsfn_release для указания того, что текущий поток больше не будет вызывать потокобезопасную функцию, или napi_tsfn_abort для указания того, что помимо текущего потока, никакой другой поток не должен делать дальнейших вызовов потокобезопасной функции. Если установлено значение napi_tsfn_abort, последующие вызовы napi_call_threadsafe_function() вернут napi_closing, и больше никаких значений не будут помещены в очередь.

Поток должен вызвать этот API, когда он прекратит использование func. Передача func в любые потокобезопасные API после вызова этого API имеет неопределённые результаты, так как func может быть уничтожена.

Этот API может вызываться из любого потока, который прекратит использование func.

napi_ref_threadsafe_function

Добавлен в: v10.6.0 Версия N-API: 4
NAPI_EXTERN napi_status
napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] func: Потокобезопасная функция, которую нужно сослаться.

Этот API используется для указания того, что цикл событий, работающий в основном потоке, не должен завершаться, пока func не будет уничтожен. Подобно uv_ref, он также идемпотентен.

Ни napi_unref_threadsafe_function не отмечает потокобезопасные функции как подлежащие уничтожению, ни napi_ref_threadsafe_function не предотвращает их уничтожения. napi_acquire_threadsafe_function и napi_release_threadsafe_function доступны для этой цели.

Этот API может вызываться только из основного потока.

napi_unref_threadsafe_function

Добавлен в: v10.6.0 Версия N-API: 4
NAPI_EXTERN napi_status
napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func); copy
  • [in] env: Среда, в которой вызывается API.
  • [in] func: Потокобезопасная функция, которую нужно отсослаться.

Этот API используется для указания того, что цикл событий, работающий в основном потоке, может завершиться до того, как func будет уничтожен. Подобно uv_unref, он также идемпотентен.

Этот API может вызываться только из основного потока.

Служебные утилиты

node_api_get_module_file_name

Добавлен в: v15.9.0, v14.18.0, v12.22.0 Версия N-API: 9
NAPI_EXTERN napi_status
node_api_get_module_file_name(napi_env env, const char** result);
 copy
  • [in] env: Среда, в которой вызывается API.
  • [out] result: URL, содержащий абсолютный путь к расположению, из которого был загружен плагин. Для файла на локальной файловой системе он будет начинаться с file://. Строка имеет нуль-терминатор, принадлежит env и поэтому не должна изменяться или освобождаться.

result может быть пустой строкой, если процесс загрузки плагина не смог установить имя файла плагина во время загрузки.

© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v18.x/docs/api/n-api.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API