Spec-Zone.ru › Node.js 20 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 — это API на языке C, обеспечивающий стабильность ABI в разных версиях Node.js и для разных уровней компилятора. API на C++ может быть проще в использовании. Для поддержки C++ проект сопровождает модуль-обёртку на C++ под названием node-addon-api. Эта обёртка предоставляет встраиваемый API на C++. Бинарные файлы, собранные с помощью 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

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

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

Ресурс Node-API предлагает отличные вводные материалы и советы разработчикам, которые только начинают работать с Node-API и node-addon-api. Дополнительные медиаматериалы доступны на странице Медиаматериалы Node-API.

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

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

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

    #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.

Разработчикам Mac все необходимые инструменты компиляции предоставляет 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 инструмента GYP от Google, поставляемая вместе с npm. Для GYP, а следовательно и для node-gyp, требуется установленный Python.

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

CMake.js

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

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

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

Три перечисленных здесь инструмента позволяют разработчикам и сопровождающим нативных аддонов создавать бинарные файлы и загружать их на общедоступные или частные серверы. Обычно эти инструменты интегрируются с системами сборки 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. 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.

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

#define NAPI_EXPERIMENTAL
#define NODE_API_EXPERIMENTAL_<FEATURE_NAME>_OPT_OUT
#include <node_api.h> copy

где <FEATURE_NAME> — имя экспериментальной функции, влияющей как на экспериментальные, так и на стабильные API.

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

До версии 9 версии Node-API дополняли друг друга и нумеровались независимо от Node.js. Это означало, что каждая версия расширяла предыдущую: она включала все API предыдущей версии и некоторые дополнения. Каждая версия Node.js поддерживала только одну версию Node-API. Например, v18.15.0 поддерживает только Node-API версии 8. Стабильность ABI обеспечивалась тем, что версия 8 была строгим надмножеством всех предыдущих версий.

Начиная с версии 9, версии Node-API по-прежнему нумеруются независимо, но для запуска аддона, работающего с Node-API версии 9, в Node-API версии 10 могут потребоваться изменения в коде. При этом стабильность ABI сохраняется: версии Node.js, поддерживающие Node-API выше версии 8, будут поддерживать все версии от 8 до самой высокой поддерживаемой версии и по умолчанию предоставлять API версии 8, если аддон не запросит более высокую версию Node-API. Такой подход позволяет эффективнее оптимизировать существующие функции Node-API, сохраняя стабильность ABI. Существующие аддоны можно и дальше запускать без повторной компиляции, используя более раннюю версию Node-API. Если аддону нужны возможности более новой версии Node-API, для использования новых функций всё равно потребуется изменить существующий код и выполнить повторную компиляцию.

В версиях Node.js, поддерживающих Node-API версии 9 и выше, определение NAPI_VERSION=X и использование существующих макросов инициализации аддонов встраивает в аддон запрошенную версию Node-API, которая будет использоваться во время выполнения. Если NAPI_VERSION не задан, по умолчанию будет использоваться версия 8.

Эта таблица может быть неактуальна для более старых веток; самые актуальные сведения приведены в последней документации API: Матрица версий Node-API

Версия Node-API Поддерживается в
9 v18.17.0+, 20.3.0+, 21.0.0 и всех последующих версиях
8 v12.22.0+, v14.17.0+, v15.12.0+, 16.0.0 и всех последующих версиях
7 v10.23.0+, v12.19.0+, v14.12.0+, 15.0.0 и всех последующих версиях
6 v10.20.0+, v12.17.0+, 14.0.0 и всех последующих версиях
5 v10.17.0+, v12.11.0+, 13.0.0 и всех последующих версиях
4 v10.16.0+, v11.8.0+, 12.0.0 и всех последующих версиях
3 v6.14.2*, 8.11.2+, v9.11.0+*, 10.0.0 и всех последующих версиях
2 v8.10.0+*, v9.3.0+*, 10.0.0 и всех последующих версиях
1 v8.6.0+**, v9.0.0+*, 10.0.0 и всех последующих версиях

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

** В Node.js 8.0.0 Node-API входил в экспериментальном статусе. Он был выпущен как Node-API версии 1, но продолжал развиваться до Node.js 8.6.0. В версиях до Node.js 8.6.0 API отличается. Мы рекомендуем 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 будет доступен только в том случае, если перед подключением node_api.h или js_native_api.h указан #define NAPI_EXPERIMENTAL. Если API, судя по всему, недоступен в версии Node.js новее указанной в added in:, вероятнее всего, причина именно в этом.

API 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, могут быть неприменимы.

Специфичные для 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 NODE_API_CALL(env, call)                                  \
  do {                                                            \
    napi_status status = (call);                                  \
    if (status != napi_ok) {                                      \
      const napi_extended_error_info* error_info = NULL;          \
      napi_get_last_error_info((env), &error_info);               \
      const char* err_message = error_info->error_message;        \
      bool is_pending;                                            \
      napi_is_exception_pending((env), &is_pending);              \
      /* If an exception is already pending, don't rethrow it */  \
      if (!is_pending) {                                          \
        const char* message = (err_message == NULL)               \
            ? "empty error message"                               \
            : err_message;                                        \
        napi_throw_error((env), NULL, message);                   \
      }                                                           \
      return NULL;                                                \
    }                                                             \
  } while(0)

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

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

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

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

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

NAPI_MODULE_INIT(/* napi_env env, napi_value exports */) {
  // 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 определяет понятие «агент» как автономную среду, в которой выполняется код 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(node_api_basic_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: Необязательная подсказка, передаваемая функции обратного вызова финализации во время сборки мусора.

Возвращает 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(node_api_basic_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: строка в кодировке UTF-8 с описанием ошибки, не зависящим от виртуальной машины.
  • engine_reserved: зарезервировано для сведений об ошибке, специфичных для виртуальной машины. В настоящее время не реализовано ни для одной виртуальной машины.
  • engine_error_code: код ошибки, специфичный для виртуальной машины. В настоящее время не реализовано ни для одной виртуальной машины.
  • error_code: код состояния Node-API, соответствующий последней ошибке.

Дополнительные сведения см. в разделе Обработка ошибок.

napi_env

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

node_api_basic_env

Стабильность: 1 — экспериментальный

Этот вариант napi_env передается синхронным финализаторам (node_api_basic_finalize). Существует подмножество Node-API, принимающих параметр типа node_api_basic_env в качестве первого аргумента. Эти API не обращаются к состоянию движка JavaScript, поэтому их безопасно вызывать из синхронных финализаторов. Передавать этим API параметр типа napi_env разрешено, однако передавать параметр типа node_api_basic_env API, обращающимся к состоянию движка JavaScript, запрещено. Попытка сделать это без приведения типа приведет к предупреждению компилятора или ошибке, если аддоны компилируются с флагами, заставляющими компилятор выдавать предупреждения и/или ошибки при передаче функции указателей неверных типов. Вызов таких API из синхронного финализатора в конечном счете приведет к завершению приложения.

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 создаются в контексте области видимости дескриптора. При вызове нативного метода из JavaScript существует область видимости дескриптора по умолчанию. Если пользователь явно не создает новую область видимости дескриптора, значения Node-API создаются в области видимости дескриптора по умолчанию. При любом вызове кода вне выполнения нативного метода (например, во время вызова обратного вызова libuv) модуль должен создать область видимости перед вызовом любых функций, которые могут привести к созданию значений JavaScript.

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

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

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

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

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 или внешние объекты, чтобы гарантировать их принадлежность к определенному типу. Эта проверка надежнее, чем 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

За исключением случаев, рассмотренных в разделе Управление временем жизни объектов, создавать область видимости дескрипторов и/или область видимости обратных вызовов внутри napi_callback не требуется.

node_api_basic_finalize
Добавлено в: v20.12.0
Стабильность: 1 — экспериментальный

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

typedef void (*node_api_basic_finalize)(node_api_basic_env env,
                                      void* finalize_data,
                                      void* finalize_hint); copy

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

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

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

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

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

    Разрешено вызывать только API Node-API, принимающие node_api_basic_env в качестве первого параметра; в противном случае приложение будет завершено с соответствующим сообщением об ошибке. Эту возможность можно отключить, определив NODE_API_EXPERIMENTAL_BASIC_ENV_OPT_OUT.

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

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

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

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

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

    Функцию этого типа больше нельзя использовать в качестве финализатора, кроме как с node_api_post_finalizer. Вместо нее необходимо использовать node_api_basic_finalize. Эту возможность можно отключить, определив NODE_API_EXPERIMENTAL_BASIC_ENV_OPT_OUT.

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

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

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
Добавлено в: v19.2.0, 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(node_api_basic_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 указывает на статически определённую строку, поэтому этот указатель можно безопасно использовать, если перед вызовом другой функции Node-API скопировать его из поля error_message (которое будет перезаписано).

Не полагайтесь на содержимое или формат каких-либо дополнительных сведений, поскольку они не подпадают под действие 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. Полезно, если асинхронный обратный вызов выбрасывает исключение, которое невозможно обработать.

Критические ошибки

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

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, представляющий дескриптор выведенного объекта Object во внешней области.

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

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

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

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

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

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

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

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

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

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

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

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

  • Экспериментальная возможность (определён NAPI_EXPERIMENTAL):

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

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, или будущая поддержка Worker могут потребовать от дополнений регистрации обработчиков очистки, которые будут вызваны после завершения работы текущей среды Node.js.

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

napi_add_env_cleanup_hook
Добавлено в: v10.2.0 Версия N-API: 3
NODE_EXTERN napi_status napi_add_env_cleanup_hook(node_api_basic_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(node_api_basic_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(
    node_api_basic_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

Чтобы определить класс, позволяющий создавать новые экземпляры (часто используется вместе с обёртыванием объектов):

// 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_env env, napi_value exports */) {
  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

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

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

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

Подробнее о задании свойств объектов см. в разделе Работа со свойствами JavaScript.

Общие сведения о сборке модулей-дополнений см. в существующей документации API.

Работа со значениями 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

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

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. Свойство длины Array устанавливается в значение переданного параметра длины. Однако при создании массива виртуальная машина не гарантирует предварительное выделение базового буфера. Это зависит от реализации виртуальной машины. Если буфер должен представлять собой непрерывный блок памяти, который можно напрямую считывать и/или записывать средствами 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, соответствующее ArrayBuffer JavaScript. 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 в миллисекундах с 1 января 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: необязательная подсказка, передаваемая обратному вызову финализации при сборке.
  • [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
  • [in] env: среда, в которой вызывается API.
  • [in] external_data: указатель на базовый байтовый буфер ArrayBuffer.
  • [in] byte_length: длина базового буфера в байтах.
  • [in] finalize_cb: необязательный обратный вызов, который вызывается при сборке ArrayBuffer. Дополнительные сведения см. в разделе napi_finalize.
  • [in] finalize_hint: необязательная подсказка, передаваемая обратному вызову финализации при сборке.
  • [out] result: napi_value, представляющий массив JavaScript ArrayBuffer.

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

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

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

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

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: необязательная подсказка, передаваемая обратному вызову финализации при сборке.
  • [out] result: napi_value, представляющий node::Buffer.

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

В некоторых средах выполнения, отличных от 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 из строки C в кодировке UTF-8.

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

node_api_symbol_for
Добавлено в: v17.5.0, v16.15.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: строка C в кодировке UTF-8, представляющая текст, который будет использоваться как описание символа.
  • [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: массив 64-битных слов uint64_t в порядке от младшего к старшему.
  • [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
Добавлено в: v20.4.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, если строка собирается в рамках завершения работы рабочего потока или основного экземпляра Node.js.
    • [in] data: значение str в виде указателя void*.
    • [in] finalize_hint: значение finalize_hint, переданное API. Дополнительные сведения см. в разделе napi_finalize. Этот параметр необязателен. Передача значения null означает, что дополнение не нужно уведомлять о сборке соответствующей строки JavaScript.
  • [in] finalize_hint: необязательная подсказка, передаваемая обратному вызову финализации при сборке.
  • [out] result: napi_value, представляющий строку JavaScript string.
  • [out] copied: была ли строка скопирована. Если да, финализатор уже был вызван для уничтожения 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
Добавлено в: v20.4.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, если строка собирается в рамках завершения работы рабочего потока или основного экземпляра Node.js.
    • [in] data: Это значение str в виде указателя void*.
    • [in] finalize_hint: Это значение finalize_hint, переданное API. Дополнительные сведения см. в разделе napi_finalize. Этот параметр необязателен. Передача значения null означает, что дополнению не нужно получать уведомление о сборке соответствующей строки JavaScript.
  • [in] finalize_hint: Необязательная подсказка, передаваемая функции финализации во время сборки.
  • [out] result: napi_value, представляющий JavaScript string.
  • [out] copied: Была ли строка скопирована. Если да, финализатор уже был вызван для уничтожения 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.

Функции для создания оптимизированных ключей свойств

Многие движки JavaScript, включая V8, используют интернированные строки в качестве ключей для установки и получения значений свойств. Обычно для создания и поиска таких строк используется хеш-таблица. Хотя это увеличивает стоимость создания каждого ключа, впоследствии производительность повышается, поскольку вместо целых строк можно сравнивать указатели на строки.

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

node_api_create_property_key_latin1
Добавлено в: v20.18.0
Стабильность: 1 - Экспериментальный
napi_status NAPI_CDECL node_api_create_property_key_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 для использования в качестве ключа свойства объектов. Собственная строка копируется. В отличие от napi_create_string_latin1, повторные вызовы этой функции с тем же указателем str могут ускорить создание запрошенного napi_value в зависимости от движка.

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

node_api_create_property_key_utf16
Добавлено в: v20.12.0
Стабильность: 1 - Экспериментальный
napi_status NAPI_CDECL node_api_create_property_key_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_property_key_utf8
Добавлено в: v20.18.0
Стабильность: 1 - Экспериментальный
napi_status NAPI_CDECL node_api_create_property_key_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.

Функции преобразования типов 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.

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 или Uint8Array.
  • [out] data: Базовый буфер данных node::Buffer или Uint8Array. Если length равен 0, это значение может быть NULL или любым другим значением указателя.
  • [out] length: Длина базового буфера данных в байтах.

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

Этот метод возвращает те же data и byte_length, что и napi_get_typedarray_info. Кроме того, napi_get_typedarray_info принимает в качестве значения node::Buffer (Uint8Array).

Этот 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, представленное количеством миллисекунд с полуночи 1 января 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 типа boolean, эквивалентный заданному JavaScript Boolean.

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

Этот API возвращает примитив C типа boolean, эквивалентный заданному 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
  • [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-битный массив в порядке от младшего байта к старшему и количество элементов в массиве. Параметрам 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, длина строки в двухбайтовых кодовых единицах без завершающего нулевого символа возвращается.
  • [in] bufsize: Размер целевого буфера. Если этого значения недостаточно, возвращаемая строка усекается и завершается нулевым символом.
  • [out] result: Количество двухбайтовых кодовых единиц, скопированных в буфер, без завершающего нулевого символа.

Возвращает 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, представляющий значение Undefined в JavaScript.

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

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

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

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

Эти 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 не является значением External.

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

  1. Поддерживается обнаружение значения External.
  2. null определяется как отдельный тип, тогда как оператор typeof в ECMAScript определил бы его как 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: Является ли указанный объект ArrayBuffer.

Возвращает 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 объект типа node::Buffer или Uint8Array.

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

Этот API проверяет, является ли переданный Object буфером или Uint8Array. Если вызывающему коду необходимо проверить, является ли значение Uint8Array, рекомендуется использовать napi_is_typedarray.

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: Представляет ли указанный napi_value объект JavaScript типа Date.

Возвращает 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_value объект типа Error.

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

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

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_value значение типа TypedArray.

Возвращает 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_value значение типа DataView.

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

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

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_value.

Возвращает 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 ArrayBuffer.

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

Как правило, 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 все ключи свойств можно представить в одной из следующих форм:

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

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

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: необязательная строка UTF-8, описывающая ключ свойства. Для свойства необходимо указать одно из значений: 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 — имён свойств объекта. Для перебора result можно использовать napi_get_array_length и napi_get_element.

Возвращает 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 вызывать собственный код. API Node-API, поддерживающие вызов собственного кода, принимают функцию обратного вызова, представленную типом napi_callback. Когда виртуальная машина JavaScript обращается к собственному коду, вызывается предоставленная функция 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: необязательное имя функции в кодировке UTF-8. В 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.

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

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 Function описаны в разделе 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 вызывает метод или аксессор свойства класса, вызывается соответствующая функция C++ napi_callback. Для обратного вызова экземпляра функция 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 информации обратного вызова.
  • [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).
  • Свойства объекта prototype функции-конструктора. При обёртывании класса 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 создан из prototype функции-конструктора, поэтому в нём уже определены все свойства и методы экземпляра.)

Обычно при обёртывании экземпляра класса следует предоставить обратный вызов финализации, который просто удаляет собственный экземпляр, полученный в качестве аргумента 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
  • [in] env: среда, в которой вызывается API.
  • [in] js_object: объект, связанный с собственным экземпляром.
  • [out] result: указатель на обёрнутый собственный экземпляр.

Возвращает napi_ok, если 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
  • [in] env: среда, в которой вызывается API.
  • [in] js_object: объект, связанный с собственным экземпляром.
  • [out] result: указатель на обёрнутый собственный экземпляр.

Возвращает napi_ok, если 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
  • [in] env: среда, в которой вызывается API.
  • [in] js_object: объект JavaScript или внешний объект, который нужно пометить.
  • [in] type_tag: тег, которым нужно пометить объект.

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

Связывает значение указателя type_tag с объектом JavaScript или внешним объектом. Затем 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
  • [in] env: среда, в которой вызывается API.
  • [in] js_object: объект JavaScript или внешний объект, тег типа которого нужно проверить.
  • [in] type_tag: тег для сравнения с тегом, найденным у объекта.
  • [out] result: указывает, совпал ли заданный тег типа с тегом типа объекта. Также возвращается false, если тег типа у объекта не найден.

Возвращает napi_ok, если 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,
                               node_api_basic_finalize finalize_cb,
                               void* finalize_hint,
                               napi_ref* result); copy
  • [in] env: среда, в которой вызывается API.
  • [in] js_object: объект JavaScript, к которому будут присоединены собственные данные.
  • [in] finalize_data: необязательные данные, передаваемые в finalize_cb.
  • [in] finalize_cb: собственный обратный вызов, который будет использоваться для освобождения собственных данных после сборки мусора для объекта JavaScript. Дополнительные сведения см. в разделе napi_finalize.
  • [in] finalize_hint: необязательная контекстная подсказка, передаваемая обратному вызову финализации.
  • [out] result: необязательная ссылка на объект JavaScript.

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

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

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

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

node_api_post_finalizer
Добавлено в: v20.10.0
Стабильность: 1 - Экспериментальный
napi_status node_api_post_finalizer(node_api_basic_env env,
                                    napi_finalize finalize_cb,
                                    void* finalize_data,
                                    void* finalize_hint); copy
  • [in] env: среда, в которой вызывается API.
  • [in] finalize_cb: собственный обратный вызов, который будет использоваться для освобождения собственных данных после сборки мусора для объекта JavaScript. Дополнительные сведения см. в разделе napi_finalize.
  • [in] finalize_data: необязательные данные, передаваемые в finalize_cb.
  • [in] finalize_hint: необязательная контекстная подсказка, передаваемая обратному вызову финализации.

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

Планирует асинхронный вызов обратного вызова napi_finalize в цикле событий.

Обычно финализаторы вызываются во время сборки объектов сборщиком мусора (GC). В этот момент вызов любого Node-API, который может привести к изменению состояния GC, будет отключён и приведёт к аварийному завершению Node.js.

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

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

Модулям-аддонам часто требуется использовать асинхронные вспомогательные средства из 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(node_api_basic_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(node_api_basic_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(node_api_basic_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, работали корректно. Для сохранения совместимости ABI с предыдущими версиями объекты napi_async_context не поддерживают сильную ссылку на объекты async_resource, чтобы избежать утечек памяти. Однако если сборщик мусора JavaScript-движка удалит async_resource до того, как napi_async_context будет уничтожен с помощью napi_async_destroy, вызов связанных с napi_async_context API, например napi_open_callback_scope и napi_make_callback, может привести к таким проблемам, как потеря асинхронного контекста при использовании API AsyncLocalStorage.

Для сохранения совместимости ABI с предыдущими версиями передача 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. Для сохранения совместимости ABI с предыдущими версиями передача 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 или Promise, поставленные 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(node_api_basic_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(node_api_basic_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, которые её поддерживают, и при этом обеспечивать запасной вариант для версий 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(node_api_basic_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 указывает на собственную память, выделенную нативным дополнением). Регистрация внешней памяти приводит к более частому запуску глобальной сборки мусора.

Промисы

Node-API предоставляет средства для создания объектов Promise, описанных в разделе 25.4 спецификации ECMA (Section 25.4). Промисы реализованы в виде пары объектов. При создании промиса с помощью napi_create_promise() создаётся объект «deferred», который возвращается вместе с Promise. Объект deferred связан с созданным Promise и является единственным способом разрешить или отклонить Promise с помощью napi_resolve_deferred() или napi_reject_deferred(). Объект 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() выполняет асинхронное действие, а затем разрешает или отклоняет deferred, завершая тем самым промис и освобождая deferred:

napi_deferred deferred;
napi_value undefined;
napi_status status;

// Create a value with which to conclude the deferred.
status = napi_get_undefined(env, &undefined);
if (status != napi_ok) return NULL;

// Resolve or reject the promise associated with the deferred depending on
// whether the asynchronous action succeeded.
if (asynchronous_action_succeeded) {
  status = napi_resolve_deferred(env, deferred, undefined);
} else {
  status = napi_reject_deferred(env, deferred, undefined);
}
if (status != napi_ok) return NULL;

// At this point the deferred has been freed, so we should assign NULL to it.
deferred = NULL; 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: вновь созданный объект deferred, который позднее можно передать в napi_resolve_deferred() или napi_reject_deferred(), чтобы соответственно разрешить или отклонить связанный с ним промис.
  • [out] promise: промис JavaScript, связанный с объектом deferred.

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

Этот API создаёт объект deferred и промис 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: объект deferred, связанный с разрешаемым промисом.
  • [in] resolution: значение, которым разрешается промис.

Этот API разрешает промис JavaScript посредством связанного с ним объекта deferred. Поэтому его можно использовать только для разрешения тех промисов JavaScript, для которых доступен соответствующий объект deferred. Это означает, что промис должен быть создан с помощью napi_create_promise(), а возвращённый этим вызовом объект deferred необходимо сохранить, чтобы передать его этому API.

Объект deferred освобождается после успешного завершения операции.

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: объект deferred, связанный с разрешаемым промисом.
  • [in] rejection: значение, которым отклоняется промис.

Этот API отклоняет промис JavaScript посредством связанного с ним объекта deferred. Поэтому его можно использовать только для отклонения тех промисов JavaScript, для которых доступен соответствующий объект deferred. Это означает, что промис должен быть создан с помощью napi_create_promise(), а возвращённый этим вызовом объект deferred необходимо сохранить, чтобы передать его этому API.

Объект deferred освобождается после успешного завершения операции.

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 нативным объектом 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(node_api_basic_env env,
                                               struct uv_loop_s** loop); copy
  • [in] env: среда, в которой вызывается API.
  • [out] loop: текущий экземпляр цикла libuv.

Примечание. Хотя libuv оставалась относительно стабильной с течением времени, она не гарантирует стабильность ABI. Следует избегать использования этой функции: из-за неё дополнение может оказаться несовместимым с разными версиями Node.js. Для многих сценариев можно использовать альтернативу — асинхронные потокобезопасные вызовы функций.

Асинхронные потокобезопасные вызовы функций

Функции 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_call_threadsafe_function() значение возврата napi_closing, поток больше не должен использовать потокобезопасную функцию, поскольку ее выделение больше не гарантируется.

Определение необходимости поддерживать работу процесса

Как и дескрипторы 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: Необязательный объект, связанный с асинхронной работой, который будет передан возможным обработчикам init async_hooks.
  • [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 будет вызвана без параметров, а в качестве значения this будет использоваться undefined. Подробнее см. в разделе napi_threadsafe_function_call_js.
  • [out] result: Асинхронная потокобезопасная функция JavaScript.

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

  • Экспериментальная функция (определено NAPI_EXPERIMENTAL):

    Необработанные исключения, выброшенные в call_js_cb, обрабатываются событием 'uncaughtException' вместо того, чтобы игнорироваться.

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(node_api_basic_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(node_api_basic_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(node_api_basic_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-v20.x/docs/api/n-api.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API