Перейти к содержанию

Node-API

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

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

Аддоны создаются / упаковываются с использованием того же подхода / инструментов, которые описаны в разделе, озаглавленном Дополнения C ++. Единственное отличие - это набор API, которые используются в машинном коде. Вместо использования V8 или Нативные абстракции для Node.js API, используются функции, доступные в Node-API.

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

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

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

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

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

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

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

Когда используешь node-addon-api вместо C API начните с API документы для node-addon-api.

В Ресурс Node-APIпредлагает отличную ориентацию и советы для разработчиков, только начинающих работать с Node-API и node-addon-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>
  • API libuv, которые также включены в Node.js и доступны через
#include <uv.h>
  • API V8 доступен через
#include <v8.h>

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

#include <node_api.h>

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

Строительство

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

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

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

xcode-select --install

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

npm install --global windows-build-tools

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

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

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

узел-гипс

узел-гипс это система сборки, основанная на gyp-next вилка Google GYP инструмент и поставляется в комплекте с npm. GYP и, следовательно, node-gyp, требуют установки Python.

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

CMake.js

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

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

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

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

узел-pre-gyp

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

предварительная сборка

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

предварительно построить

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

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

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

#include <node_api.h>

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

#define NAPI_VERSION 3
#include <node_api.h>

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

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

#define NAPI_EXPERIMENTAL
#include <node_api.h>

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

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

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

1 2 3
v6.x v6.14.2*
v8.x v8.6.0** v8.10.0* v8.11.2
v9.x v9.0.0* v9.3.0* v9.11.0*
≥ v10.x all releases all releases all releases
4 5 6 7 8
v10.x v10.16.0 v10.17.0 v10.20.0 v10.23.0
v11.x v11.8.0
v12.x v12.0.0 v12.11.0 v12.17.0 v12.19.0 v12.22.0
v13.x v13.0.0 v13.0.0
v14.x v14.0.0 v14.0.0 v14.0.0 v14.12.0 v14.17.0
v15.x v15.0.0 v15.0.0 v15.0.0 v15.0.0 v15.12.0
v16.x v16.0.0 v16.0.0 v16.0.0 v16.0.0 v16.0.0

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

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

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

API-интерфейсы Node, связанные строго с доступом к функциям 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_
// addon.c
#include "addon.h"

#define NAPI_CALL(env, call)                                      \
  do {                                                            \
    napi_status status = (call);                                  \
    if (status != napi_ok) {                                      \
      const napi_extended_error_info* error_info = NULL;          \
      napi_get_last_error_info((env), &error_info);               \
      bool is_pending;                                            \
      napi_is_exception_pending((env), &is_pending);              \
      if (!is_pending) {                                          \
        const char* message = (error_info->error_message == NULL) \
            ? "empty error message"                               \
            : error_info->error_message;                          \
        napi_throw_error((env), NULL, message);                   \
        return NULL;                                              \
      }                                                           \
    }                                                             \
  } while(0)

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

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

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

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

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

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

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

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

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

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

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

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

napi_set_instance_data

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

Возврат napi_ok если API удалось.

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

napi_get_instance_data

napi_status napi_get_instance_data(napi_env env,
                                   void** data);
  • [in] env: Среда, в которой вызывается вызов Node-API.
  • [out] data: Элемент данных, который ранее был связан с текущим работающим агентом при вызове napi_set_instance_data().

Возврат napi_ok если API удалось.

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

Базовые типы данных Node-API

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

napi_status

Интегральный код состояния, указывающий на успешность или неудачу вызова 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_status;

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

napi_extended_error_info

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

Увидеть Обработка ошибок раздел для дополнительной информации.

napi_env

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

napi_value

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

napi_threadsafe_function

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

napi_threadsafe_function_release_mode

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

typedef enum {
  napi_tsfn_release,
  napi_tsfn_abort
} napi_threadsafe_function_release_mode;

napi_threadsafe_function_call_mode

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

typedef enum {
  napi_tsfn_nonblocking,
  napi_tsfn_blocking
} napi_threadsafe_function_call_mode;

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

napi_handle_scope

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

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

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

napi_escapable_handle_scope

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

napi_ref

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

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

napi_type_tag

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

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

napi_async_cleanup_hook_handle

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

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

napi_callback_info

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

napi_callback

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

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

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

napi_finalize

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

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

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

napi_async_execute_callback

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

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

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

napi_async_complete_callback

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

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

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

napi_threadsafe_function_call_js

Указатель на функцию, используемый с вызовами асинхронных поточно-ориентированных функций. Обратный вызов будет вызываться в основном потоке. Его цель - использовать элемент данных, поступающий через очередь из одного из вторичных потоков, для создания параметров, необходимых для вызова в 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);
  • [in] env: Среда, используемая для вызовов API, или NULL если потокобезопасная функция срывается и data может потребоваться освободить.
  • [in] js_callback: Вызываемая функция JavaScript или NULL если потокобезопасная функция срывается и data может потребоваться освободить. Это также может быть NULL если потокобезопасная функция была создана без js_callback.
  • [in] context: Необязательные данные, с которыми была создана поточно-ориентированная функция.
  • [in] data: Данные, созданные вторичным потоком. Обратный вызов отвечает за преобразование этих собственных данных в значения JavaScript (с функциями Node-API), которые могут быть переданы как параметры, когда js_callback вызывается. Этот указатель полностью управляется потоками и этим обратным вызовом. Таким образом, этот обратный вызов должен освободить данные.

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

napi_async_cleanup_hook

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

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

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

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

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

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

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

napi_get_last_error_info

napi_status
napi_get_last_error_info(napi_env env,
                         const napi_extended_error_info** result);
  • [in] env: Среда, в которой вызывается API.
  • [out] result: The napi_extended_error_info структура с дополнительной информацией об ошибке.

Возврат napi_ok если API удалось.

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

Содержание napi_extended_error_info возвращенный действителен только до тех пор, пока функция Node-API не будет вызвана на том же самом env.

Не полагайтесь на содержание или формат какой-либо расширенной информации, поскольку она не подлежит 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 а также napi_is_error.

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

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

originalName [code]

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

TypeError [ERR_ERROR_1]

napi_throw

NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error);
  • [in] env: Среда, в которой вызывается API.
  • [in] error: Выбрасываемое значение JavaScript.

Возврат napi_ok если API удалось.

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

napi_throw_error

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

Возврат napi_ok если API удалось.

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

napi_throw_type_error

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

Возврат napi_ok если API удалось.

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

napi_throw_range_error

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

Возврат napi_ok если API удалось.

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

napi_is_error

NAPI_EXTERN napi_status napi_is_error(napi_env env,
                                      napi_value value,
                                      bool* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] value: The napi_value быть проверенным.
  • [out] result: Логическое значение, равное истине, если napi_value представляет ошибку, в противном случае - false.

Возврат napi_ok если API удалось.

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

napi_create_error

NAPI_EXTERN napi_status napi_create_error(napi_env env,
                                          napi_value code,
                                          napi_value msg,
                                          napi_value* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] code: По желанию napi_value со строкой кода ошибки, которая будет связана с ошибкой.
  • [in] msg: napi_value который ссылается на JavaScript string использоваться в качестве сообщения для Error.
  • [out] result: napi_value представляющий созданную ошибку.

Возврат napi_ok если API удалось.

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

napi_create_type_error

NAPI_EXTERN napi_status napi_create_type_error(napi_env env,
                                               napi_value code,
                                               napi_value msg,
                                               napi_value* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] code: По желанию napi_value со строкой кода ошибки, которая будет связана с ошибкой.
  • [in] msg: napi_value который ссылается на JavaScript string использоваться в качестве сообщения для Error.
  • [out] result: napi_value представляющий созданную ошибку.

Возврат napi_ok если API удалось.

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

napi_create_range_error

NAPI_EXTERN napi_status napi_create_range_error(napi_env env,
                                                napi_value code,
                                                napi_value msg,
                                                napi_value* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] code: По желанию napi_value со строкой кода ошибки, которая будет связана с ошибкой.
  • [in] msg: napi_value который ссылается на JavaScript string использоваться в качестве сообщения для Error.
  • [out] result: napi_value представляющий созданную ошибку.

Возврат napi_ok если API удалось.

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

napi_get_and_clear_last_exception

napi_status napi_get_and_clear_last_exception(napi_env env,
                                              napi_value* result);
  • [in] env: Среда, в которой вызывается API.
  • [out] result: Исключение, если одно ожидает рассмотрения, NULL иначе.

Возврат napi_ok если API удалось.

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

napi_is_exception_pending

napi_status napi_is_exception_pending(napi_env env, bool* result);
  • [in] env: Среда, в которой вызывается API.
  • [out] result: Логическое значение, которое имеет значение true, если исключение ожидает обработки.

Возврат napi_ok если API удалось.

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

napi_fatal_exception

napi_status napi_fatal_exception(napi_env env, napi_value err);
  • [in] env: Среда, в которой вызывается API.
  • [in] err: Ошибка, передаваемая в 'uncaughtException'.

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

Неустранимые ошибки

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

napi_fatal_error

NAPI_NO_RETURN void napi_fatal_error(const char* location,
                                     size_t location_len,
                                     const char* message,
                                     size_t message_len);
  • [in] location: Необязательное расположение, в котором произошла ошибка.
  • [in] location_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
}

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

Чтобы справиться с этим случаем, 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;
  }
}

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

Методы, доступные для открытия / закрытия экранируемых областей: napi_open_escapable_handle_scope а также napi_close_escapable_handle_scope.

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

napi_open_handle_scope

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

Возврат napi_ok если API удалось.

Этот API открывает новые возможности.

napi_close_handle_scope

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

Возврат napi_ok если API удалось.

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

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

napi_open_escapable_handle_scope

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

Возврат napi_ok если API удалось.

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

napi_close_escapable_handle_scope

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

Возврат napi_ok если API удалось.

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

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

napi_escape_handle

napi_status napi_escape_handle(napi_env env,
                               napi_escapable_handle_scope scope,
                               napi_value escapee,
                               napi_value* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] 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 предоставляет методы для создания постоянных ссылок на объект. Каждая постоянная ссылка имеет связанный счетчик со значением 0 или выше. Счетчик определяет, будет ли ссылка поддерживать соответствующий объект в рабочем состоянии. Ссылки со счетом 0 не препятствуют сбору объекта и часто называются «слабыми» ссылками. Любое значение счетчика больше 0 предотвратит сбор объекта.

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

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

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

napi_create_reference

NAPI_EXTERN napi_status napi_create_reference(napi_env env,
                                              napi_value value,
                                              uint32_t initial_refcount,
                                              napi_ref* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] value: napi_value представляющий Object на который нам нужна ссылка.
  • [in] initial_refcount: Начальный счетчик ссылок для новой ссылки.
  • [out] result: napi_ref указывая на новую ссылку.

Возврат napi_ok если API удалось.

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

napi_delete_reference

NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref);
  • [in] env: Среда, в которой вызывается API.
  • [in] ref: napi_ref быть удаленным.

Возврат napi_ok если API удалось.

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

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

napi_reference_ref

NAPI_EXTERN napi_status napi_reference_ref(napi_env env,
                                           napi_ref ref,
                                           uint32_t* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] ref: napi_ref для которого счетчик ссылок будет увеличиваться.
  • [out] result: Новый счетчик ссылок.

Возврат napi_ok если API удалось.

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

napi_reference_unref

NAPI_EXTERN napi_status napi_reference_unref(napi_env env,
                                             napi_ref ref,
                                             uint32_t* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] ref: napi_ref для которого счетчик ссылок будет уменьшен.
  • [out] result: Новый счетчик ссылок.

Возврат napi_ok если API удалось.

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

napi_get_reference_value

NAPI_EXTERN napi_status napi_get_reference_value(napi_env env,
                                                 napi_ref ref,
                                                 napi_value* result);

в napi_value passed в этих методах или вне их - дескриптор объекта, к которому относится ссылка.

  • [in] env: Среда, в которой вызывается API.
  • [in] ref: napi_ref для чего мы запрашиваем соответствующие Object.
  • [out] result: The napi_value для Object упомянутый napi_ref.

Возврат napi_ok если API удалось.

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

Очистка при выходе из текущего экземпляра Node.js

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

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

napi_add_env_cleanup_hook

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

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

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

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

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

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

napi_remove_env_cleanup_hook

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

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

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

napi_add_async_cleanup_hook

NAPI_EXTERN napi_status napi_add_async_cleanup_hook(
    napi_env env,
    napi_async_cleanup_hook hook,
    void* arg,
    napi_async_cleanup_hook_handle* remove_handle);
  • [in] env: Среда, в которой вызывается API.
  • [in] 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

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

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

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

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

NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)

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

napi_value Init(napi_env env, napi_value exports);

Возвращаемое значение из 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;
}

Чтобы установить функцию, возвращаемую 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;
}

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

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

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

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

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

  return exports;
}

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

NAPI_MODULE_INIT() {
  napi_value answer;
  napi_status result;

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

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

  return exports;
}

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

Переменные 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

typedef enum {
  napi_key_include_prototypes,
  napi_key_own_only
} napi_key_collection_mode;

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

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

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

napi_key_filter

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

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

napi_key_conversion

typedef enum {
  napi_key_keep_numbers,
  napi_key_numbers_to_strings
} napi_key_conversion;

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

napi_valuetype

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

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

Значение типа 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;

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

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

napi_create_array

napi_status napi_create_array(napi_env env, napi_value* result)
  • [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

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

Возврат napi_ok если API удалось.

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

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

napi_create_arraybuffer

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

Возврат napi_ok если API удалось.

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

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

napi_create_buffer

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

Возврат napi_ok если API удалось.

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

napi_create_buffer_copy

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

Возврат napi_ok если API удалось.

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

napi_create_date

napi_status napi_create_date(napi_env env,
                             double time,
                             napi_value* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] time: Значение времени ECMAScript в миллисекундах с 1 января 1970 года по всемирному координированному времени.
  • [out] result: А napi_value представляющий JavaScript Date.

Возврат napi_ok если API удалось.

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

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

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

napi_create_external

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

Возврат napi_ok если API удалось.

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

API добавляет napi_finalize обратный вызов, который будет вызван, когда только что созданный объект JavaScript будет готов для сборки мусора. Это похоже на napi_wrap() Кроме этого:

  • собственные данные не могут быть получены позже с помощью napi_unwrap(),
  • и его нельзя удалить позже, используя napi_remove_wrap(), а также
  • объект, созданный API, можно использовать с napi_wrap().

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

napi_create_external_arraybuffer

napi_status
napi_create_external_arraybuffer(napi_env env,
                                 void* external_data,
                                 size_t byte_length,
                                 napi_finalize finalize_cb,
                                 void* finalize_hint,
                                 napi_value* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] external_data: Указатель на нижележащий байтовый буфер ArrayBuffer.
  • [in] byte_length: Длина в байтах нижележащего буфера.
  • [in] finalize_cb: Дополнительный обратный вызов для вызова, когда ArrayBuffer собирается. napi_finalize предоставляет более подробную информацию.
  • [in] finalize_hint: Необязательная подсказка для перехода к обратному вызову finalize во время сбора.
  • [out] result: А napi_value представляющий JavaScript ArrayBuffer.

Возврат napi_ok если API удалось.

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

API добавляет napi_finalize обратный вызов, который будет вызван, когда только что созданный объект JavaScript будет готов для сборки мусора. Это похоже на napi_wrap() Кроме этого:

  • собственные данные не могут быть получены позже с помощью napi_unwrap(),
  • и его нельзя удалить позже, используя napi_remove_wrap(), а также
  • объект, созданный API, можно использовать с napi_wrap().

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

napi_create_external_buffer

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

Возврат napi_ok если API удалось.

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

API добавляет napi_finalize обратный вызов, который будет вызван, когда только что созданный объект JavaScript будет готов для сборки мусора. Это похоже на napi_wrap() Кроме этого:

  • собственные данные не могут быть получены позже с помощью napi_unwrap(),
  • и его нельзя удалить позже, используя napi_remove_wrap(), а также
  • объект, созданный API, можно использовать с napi_wrap().

Для Node.js> = 4 Buffers находятся Uint8Arrayс.

napi_create_object

napi_status napi_create_object(napi_env env, napi_value* result)
  • [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

napi_status napi_create_symbol(napi_env env,
                               napi_value description,
                               napi_value* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] description: По желанию napi_value который относится к JavaScript string быть установленным в качестве описания символа.
  • [out] result: А napi_value представляющий JavaScript symbol.

Возврат napi_ok если API удалось.

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

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

napi_create_typedarray

napi_status napi_create_typedarray(napi_env env,
                                   napi_typedarray_type type,
                                   size_t length,
                                   napi_value arraybuffer,
                                   size_t byte_offset,
                                   napi_value* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] 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

napi_status napi_create_dataview(napi_env env,
                                 size_t byte_length,
                                 napi_value arraybuffer,
                                 size_t byte_offset,
                                 napi_value* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] 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

napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result)
  • [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

napi_status napi_create_uint32(napi_env env, uint32_t value, napi_value* result)
  • [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

napi_status napi_create_int64(napi_env env, int64_t value, napi_value* result)
  • [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

napi_status napi_create_double(napi_env env, double value, napi_value* result)
  • [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

napi_status napi_create_bigint_int64(napi_env env,
                                     int64_t value,
                                     napi_value* result);
  • [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

napi_status napi_create_bigint_uint64(napi_env env,
                                      uint64_t value,
                                      napi_value* result);
  • [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

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

Возврат napi_ok если API удалось.

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

Результирующий BigInt рассчитывается как: (–1)sign_bit (words[0] × (264)0 + words[1] × (264)1 +…)

napi_create_string_latin1

napi_status napi_create_string_latin1(napi_env env,
                                      const char* str,
                                      size_t length,
                                      napi_value* result);
  • [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.

napi_create_string_utf16

napi_status napi_create_string_utf16(napi_env env,
                                     const char16_t* str,
                                     size_t length,
                                     napi_value* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] 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.

napi_create_string_utf8

napi_status napi_create_string_utf8(napi_env env,
                                    const char* str,
                                    size_t length,
                                    napi_value* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] 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

napi_status napi_get_array_length(napi_env env,
                                  napi_value value,
                                  uint32_t* result)
  • [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

napi_status napi_get_arraybuffer_info(napi_env env,
                                      napi_value arraybuffer,
                                      void** data,
                                      size_t* byte_length)
  • [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, которые могут вызвать GC.

napi_get_buffer_info

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

Возврат napi_ok если API удалось.

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

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

napi_get_prototype

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

Возврат napi_ok если API удалось.

napi_get_typedarray_info

napi_status napi_get_typedarray_info(napi_env env,
                                     napi_value typedarray,
                                     napi_typedarray_type* type,
                                     size_t* length,
                                     void** data,
                                     napi_value* arraybuffer,
                                     size_t* byte_offset)
  • [in] env: Среда, в которой вызывается API.
  • [in] typedarray: napi_value представляющий TypedArray чьи свойства запрашивать.
  • [out] type: Скалярный тип данных элементов внутри TypedArray.
  • [out] length: Количество элементов в TypedArray.
  • [out] data: Буфер данных, лежащий в основе TypedArray скорректировано byte_offset значение так, чтобы оно указывало на первый элемент в TypedArray. Если длина массива равна 0, это может быть NULL или любое другое значение указателя.
  • [out] arraybuffer: The ArrayBuffer лежащий в основе TypedArray.
  • [out] byte_offset: Байтовое смещение в базовом собственном массиве, в котором расположен первый элемент массивов. Значение параметра данных уже настроено так, чтобы данные указывали на первый элемент в массиве. Следовательно, первый байт собственного массива будет в data - byte_offset.

Возврат napi_ok если API удалось.

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

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

napi_get_dataview_info

napi_status napi_get_dataview_info(napi_env env,
                                   napi_value dataview,
                                   size_t* byte_length,
                                   void** data,
                                   napi_value* arraybuffer,
                                   size_t* byte_offset)
  • [in] env: Среда, в которой вызывается API.
  • [in] 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 удалось.

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

napi_get_date_value

napi_status napi_get_date_value(napi_env env,
                                napi_value value,
                                double* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] value: napi_value представляющий JavaScript Date.
  • [out] result: Временная стоимость как double представлены в миллисекундах с полуночи в начале 1 января 1970 года по всемирному координированному времени.

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

Возврат napi_ok если API удалось. Если не свидание napi_value передается в это возвращается napi_date_expected.

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

napi_get_value_bool

napi_status napi_get_value_bool(napi_env env, napi_value value, bool* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] value: napi_value представляющий JavaScript Boolean.
  • [out] result: C логический примитивный эквивалент данного JavaScript Boolean.

Возврат napi_ok если API удалось. Если не логическое napi_value передается в это возвращается napi_boolean_expected.

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

napi_get_value_double

napi_status napi_get_value_double(napi_env env,
                                  napi_value value,
                                  double* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] value: napi_value представляющий JavaScript number.
  • [out] result: C двойной примитивный эквивалент данного JavaScript number.

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

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

napi_get_value_bigint_int64

napi_status napi_get_value_bigint_int64(napi_env env,
                                        napi_value value,
                                        int64_t* result,
                                        bool* lossless);
  • [in] env: Среда, в которой вызывается API.
  • [in] 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

napi_status napi_get_value_bigint_uint64(napi_env env,
                                        napi_value value,
                                        uint64_t* result,
                                        bool* lossless);
  • [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

napi_status napi_get_value_bigint_words(napi_env env,
                                        napi_value value,
                                        int* sign_bit,
                                        size_t* word_count,
                                        uint64_t* words);
  • [in] env: Среда, в которой вызывается API.
  • [in] 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

napi_status napi_get_value_external(napi_env env,
                                    napi_value value,
                                    void** result)
  • [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

napi_status napi_get_value_int32(napi_env env,
                                 napi_value value,
                                 int32_t* result)
  • [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-х битов. Это может привести к тому, что большое положительное число станет отрицательным, если значение> 2.31 год - 1.

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

napi_get_value_int64

napi_status napi_get_value_int64(napi_env env,
                                 napi_value value,
                                 int64_t* result)
  • [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

napi_status napi_get_value_string_latin1(napi_env env,
                                         napi_value value,
                                         char* buf,
                                         size_t bufsize,
                                         size_t* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] 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

napi_status napi_get_value_string_utf8(napi_env env,
                                       napi_value value,
                                       char* buf,
                                       size_t bufsize,
                                       size_t* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] 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

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

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

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

napi_get_value_uint32

napi_status napi_get_value_uint32(napi_env env,
                                  napi_value value,
                                  uint32_t* result)
  • [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

napi_status napi_get_boolean(napi_env env, bool value, napi_value* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] value: Значение получаемого логического значения.
  • [out] result: napi_value представляющий JavaScript Boolean синглтон для получения.

Возврат napi_ok если API удалось.

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

napi_get_global

napi_status napi_get_global(napi_env env, napi_value* result)
  • [in] env: Среда, в которой вызывается API.
  • [out] result: napi_value представляющий JavaScript global объект.

Возврат napi_ok если API удалось.

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

napi_get_null

napi_status napi_get_null(napi_env env, napi_value* result)
  • [in] env: Среда, в которой вызывается API.
  • [out] result: napi_value представляющий JavaScript null объект.

Возврат napi_ok если API удалось.

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

napi_get_undefined

napi_status napi_get_undefined(napi_env env, napi_value* result)
  • [in] env: Среда, в которой вызывается API.
  • [out] result: napi_value представляет неопределенное значение JavaScript.

Возврат napi_ok если API удалось.

Этот API возвращает неопределенный объект.

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

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

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

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

napi_coerce_to_bool

napi_status napi_coerce_to_bool(napi_env env,
                                napi_value value,
                                napi_value* result)
  • [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

napi_status napi_coerce_to_number(napi_env env,
                                  napi_value value,
                                  napi_value* result)
  • [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

napi_status napi_coerce_to_object(napi_env env,
                                  napi_value value,
                                  napi_value* result)
  • [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

napi_status napi_coerce_to_string(napi_env env,
                                  napi_value value,
                                  napi_value* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] value: Значение JavaScript для принуждения.
  • [out] result: napi_value представляющий принудительный JavaScript string.

Возврат napi_ok если API удалось.

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

napi_typeof

napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] value: Значение JavaScript, тип которого запрашивается.
  • [out] result: Тип значения JavaScript.

Возврат napi_ok если API удалось.

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

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

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

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

napi_instanceof

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

Возврат napi_ok если API удалось.

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

napi_is_array

napi_status napi_is_array(napi_env env, napi_value value, bool* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] value: Значение JavaScript для проверки.
  • [out] result: Является ли данный объект массивом.

Возврат napi_ok если API удалось.

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

napi_is_arraybuffer

napi_status napi_is_arraybuffer(napi_env env, napi_value value, bool* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] value: Значение JavaScript для проверки.
  • [out] result: Является ли данный объект ArrayBuffer.

Возврат napi_ok если API удалось.

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

napi_is_buffer

napi_status napi_is_buffer(napi_env env, napi_value value, bool* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] value: Значение JavaScript для проверки.
  • [out] result: Будь то данный napi_value представляет node::Buffer объект.

Возврат napi_ok если API удалось.

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

napi_is_date

napi_status napi_is_date(napi_env env, napi_value value, bool* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] value: Значение JavaScript для проверки.
  • [out] result: Будь то данный napi_value представляет собой JavaScript Date объект.

Возврат napi_ok если API удалось.

Этот API проверяет, Object прошла дата.

napi_is_error

napi_status napi_is_error(napi_env env, napi_value value, bool* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] value: Значение JavaScript для проверки.
  • [out] result: Будь то данный napi_value представляет собой Error объект.

Возврат napi_ok если API удалось.

Этот API проверяет, Object прошел в Error.

napi_is_typedarray

napi_status napi_is_typedarray(napi_env env, napi_value value, bool* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] value: Значение JavaScript для проверки.
  • [out] result: Будь то данный napi_value представляет TypedArray.

Возврат napi_ok если API удалось.

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

napi_is_dataview

napi_status napi_is_dataview(napi_env env, napi_value value, bool* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] value: Значение JavaScript для проверки.
  • [out] result: Будь то данный napi_value представляет DataView.

Возврат napi_ok если API удалось.

Этот API проверяет, Object прошел в DataView.

napi_strict_equals

napi_status napi_strict_equals(napi_env env,
                               napi_value lhs,
                               napi_value rhs,
                               bool* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] lhs: Значение JavaScript для проверки.
  • [in] rhs: Значение JavaScript для проверки.
  • [out] result: Будь то два napi_value объекты равны.

Возврат napi_ok если API удалось.

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

napi_detach_arraybuffer

napi_status napi_detach_arraybuffer(napi_env env,
                                    napi_value arraybuffer)
  • [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

napi_status napi_is_detached_arraybuffer(napi_env env,
                                         napi_value arraybuffer,
                                         bool* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] arraybuffer: JavaScript ArrayBuffer быть проверенным.
  • [out] result: Будь то arraybuffer отделен.

Возврат napi_ok если API удалось.

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

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

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

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

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

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

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

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

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

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

Эквивалент может быть выполнен с использованием значений 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;

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

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

Эквивалент может быть выполнен с использованием значений 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;

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

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

Ниже приводится приблизительный эквивалент аналога 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;

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

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

Ниже приводится приблизительный эквивалент аналога Node-API:

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;

Структуры

napi_property_attributes

typedef enum {
  napi_default = 0,
  napi_writable = 1 << 0,
  napi_enumerable = 1 << 1,
  napi_configurable = 1 << 2,

  // Used with napi_define_class to distinguish static properties
  // from instance properties. Ignored by napi_define_properties.
  napi_static = 1 << 10,

  // Default for class methods.
  napi_default_method = napi_writable | napi_configurable,

  // Default for object properties, like in JS obj[prop].
  napi_default_jsproperty = napi_writable |
                          napi_enumerable |
                          napi_configurable,
} napi_property_attributes;

napi_property_attributes - это флаги, используемые для управления поведением свойств, установленных для объекта JavaScript. Кроме как napi_static они соответствуют атрибутам, перечисленным в Раздел 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;
  • utf8name: Необязательная строка, описывающая ключ свойства, в кодировке UTF8. Один из utf8name или name должны быть предусмотрены для собственности.
  • name: По желанию napi_value который указывает на строку или символ JavaScript, который будет использоваться в качестве ключа для свойства. Один из utf8name или name должны быть предусмотрены для собственности.
  • value: Значение, полученное при доступе к свойству, если свойство является свойством данных. Если это передано, установите getter, setter, method а также data к NULL (поскольку эти члены не будут использоваться).
  • getter: Функция, вызываемая при получении доступа к свойству. Если это передано, установите value а также method к NULL (поскольку эти члены не будут использоваться). Данная функция неявно вызывается средой выполнения, когда к свойству обращаются из кода JavaScript (или если получение свойства выполняется с помощью вызова Node-API). napi_callback предоставляет более подробную информацию.
  • setter: Функция, вызываемая при выполнении заданного доступа к свойству. Если это передано, установите value а также method к NULL (поскольку эти члены не будут использоваться). Данная функция неявно вызывается средой выполнения, когда свойство устанавливается из кода JavaScript (или если установка свойства выполняется с помощью вызова Node-API). napi_callback предоставляет более подробную информацию.
  • method: Установите это, чтобы сделать объект дескриптора свойства value свойство быть функцией JavaScript, представленной method. Если это передано, установите value, getter а также setter к NULL (поскольку эти члены не будут использоваться). napi_callback предоставляет более подробную информацию.
  • attributes: Атрибуты, связанные с конкретным свойством. Видеть napi_property_attributes.
  • data: Данные обратного вызова, переданные в method, getter а также setter если эта функция вызвана.

Функции

napi_get_property_names

napi_status napi_get_property_names(napi_env env,
                                    napi_value object,
                                    napi_value* result);
  • [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

napi_get_all_property_names(napi_env env,
                            napi_value object,
                            napi_key_collection_mode key_mode,
                            napi_key_filter key_filter,
                            napi_key_conversion key_conversion,
                            napi_value* result);
  • [in] env: Среда, в которой вызывается вызов Node-API.
  • [in] object: Объект, из которого нужно получить свойства.
  • [in] key_mode: Следует ли также получать свойства прототипа.
  • [in] key_filter: Какие свойства извлекать (перечислимые / читаемые / записываемые).
  • [in] key_conversion: Преобразовывать ли ключи пронумерованных свойств в строки.
  • [out] result: А napi_value представляющий массив значений JavaScript, представляющих имена свойств объекта. napi_get_array_length а также napi_get_element можно использовать для перебора result.

Возврат napi_ok если API удалось.

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

napi_set_property

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

Возврат napi_ok если API удалось.

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

napi_get_property

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

Возврат napi_ok если API удалось.

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

napi_has_property

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

Возврат napi_ok если API удалось.

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

napi_delete_property

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

Возврат napi_ok если API удалось.

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

napi_has_own_property

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

Возврат napi_ok если API удалось.

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

napi_set_ named_property

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

Возврат napi_ok если API удалось.

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

napi_get_ named_property

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

Возврат napi_ok если API удалось.

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

napi_has_ named_property

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

Возврат napi_ok если API удалось.

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

napi_set_element

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

Возврат napi_ok если API удалось.

Этот API устанавливает и элемент на Object прошел внутрь.

napi_get_element

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

Возврат napi_ok если API удалось.

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

napi_has_element

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

Возврат napi_ok если API удалось.

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

napi_delete_element

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

Возврат napi_ok если API удалось.

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

napi_define_properties

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

Возврат napi_ok если API удалось.

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

napi_object_freeze

napi_status napi_object_freeze(napi_env env,
                               napi_value object);
  • [in] env: Среда, в которой вызывается вызов Node-API.
  • [in] object: Объект, который нужно заморозить.

Возврат napi_ok если API удалось.

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

napi_object_seal

napi_status napi_object_seal(napi_env env,
                             napi_value object);
  • [in] env: Среда, в которой вызывается вызов Node-API.
  • [in] object: Объект, который нужно запечатать.

Возврат napi_ok если API удалось.

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

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

Node-API предоставляет набор API-интерфейсов, которые позволяют коду JavaScript возвращаться в собственный код. 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

NAPI_EXTERN napi_status napi_call_function(napi_env env,
                                           napi_value recv,
                                           napi_value func,
                                           size_t argc,
                                           const napi_value* argv,
                                           napi_value* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] recv: The 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;
}

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

// Get the function named "AddTwo" on the global object
napi_value global, add_two, arg;
napi_status status = napi_get_global(env, &global);
if (status != napi_ok) return;

status = napi_get_named_property(env, global, "AddTwo", &add_two);
if (status != napi_ok) return;

// const arg = 1337
status = napi_create_int32(env, 1337, &arg);
if (status != napi_ok) return;

napi_value* argv = &arg;
size_t argc = 1;

// AddTwo(arg);
napi_value return_val;
status = napi_call_function(env, global, add_two, argc, argv, &return_val);
if (status != napi_ok) return;

// Convert the result back to a native type
int32_t result;
status = napi_get_value_int32(env, return_val, &result);
if (status != napi_ok) return;

napi_create_function

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

Возврат napi_ok если API удалось.

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

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

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

napi_value SayHello(napi_env env, napi_callback_info info) {
  printf("Hello\n");
  return NULL;
}

napi_value Init(napi_env env, napi_value exports) {
  napi_status status;

  napi_value fn;
  status = napi_create_function(env, NULL, 0, SayHello, NULL, &fn);
  if (status != napi_ok) return NULL;

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

  return exports;
}

NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)

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

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

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

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

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

napi_get_cb_info

napi_status napi_get_cb_info(napi_env env,
                             napi_callback_info cbinfo,
                             size_t* argc,
                             napi_value* argv,
                             napi_value* thisArg,
                             void** data)
  • [in] env: Среда, в которой вызывается API.
  • [in] cbinfo: Информация обратного вызова, переданная в функцию обратного вызова.
  • [in-out] argc: Определяет длину предоставленного argv массив и получает фактическое количество аргументов.
  • [out] argv: Буфер, в который napi_value представляющие аргументы копируются. Если аргументов больше, чем предоставлено, копируется только запрошенное количество аргументов. Если приведено меньше аргументов, чем заявлено, остальные argv наполнен napi_value ценности, которые представляют undefined.
  • [out] this: Получает JavaScript this аргумент для звонка.
  • [out] data: Получает указатель данных для обратного вызова.

Возврат napi_ok если API удалось.

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

napi_get_new_target

napi_status napi_get_new_target(napi_env env,
                                napi_callback_info cbinfo,
                                napi_value* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] cbinfo: Информация обратного вызова, переданная в функцию обратного вызова.
  • [out] result: The new.target вызова конструктора.

Возврат napi_ok если API удалось.

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

napi_new_instance

napi_status napi_new_instance(napi_env env,
                              napi_value cons,
                              size_t argc,
                              napi_value* argv,
                              napi_value* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] cons: napi_value представляющий функцию JavaScript, которая должна быть вызвана как конструктор.
  • [in] argc: Количество элементов в argv множество.
  • [in] argv: Массив значений JavaScript как napi_value представление аргументов конструктору.
  • [out] result: napi_value представляющий возвращаемый объект JavaScript, который в данном случае является сконструированным объектом.

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

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

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

Следующее можно приблизительно оценить в 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);

Возврат napi_ok если API удалось.

Перенос объекта

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

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

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

napi_value MyClass_constructor = NULL;
status = napi_get_reference_value(env, MyClass::es_constructor, &MyClass_constructor);
assert(napi_ok == status);
bool is_instance = false;
status = napi_instanceof(env, es_this, MyClass_constructor, &is_instance);
assert(napi_ok == status);
if (is_instance) {
  // napi_unwrap() ...
} else {
  // otherwise...
}

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

Бывают случаи, когда 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
}

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

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

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

С этой целью 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;
  }
}

napi_define_class

napi_status napi_define_class(napi_env env,
                              const char* utf8name,
                              size_t length,
                              napi_callback constructor,
                              void* data,
                              size_t property_count,
                              const napi_property_descriptor* properties,
                              napi_value* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] 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

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

Возврат napi_ok если API удалось.

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

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

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

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

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

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

napi_unwrap

napi_status napi_unwrap(napi_env env,
                        napi_value js_object,
                        void** result);
  • [in] env: Среда, в которой вызывается API.
  • [in] js_object: Объект, связанный с собственным экземпляром.
  • [out] result: Указатель на обернутый собственный экземпляр.

Возврат napi_ok если API удалось.

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

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

napi_remove_wrap

napi_status napi_remove_wrap(napi_env env,
                             napi_value js_object,
                             void** result);
  • [in] env: Среда, в которой вызывается API.
  • [in] js_object: Объект, связанный с собственным экземпляром.
  • [out] result: Указатель на обернутый собственный экземпляр.

Возврат napi_ok если API удалось.

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

napi_type_tag_object

napi_status napi_type_tag_object(napi_env env,
                                 napi_value js_object,
                                 const napi_type_tag* type_tag);
  • [in] env: Среда, в которой вызывается API.
  • [in] 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

napi_status napi_check_object_type_tag(napi_env env,
                                       napi_value js_object,
                                       const napi_type_tag* type_tag,
                                       bool* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] 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

napi_status napi_add_finalizer(napi_env env,
                               napi_value js_object,
                               void* native_object,
                               napi_finalize finalize_cb,
                               void* finalize_hint,
                               napi_ref* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] js_object: Объект JavaScript, к которому будут прикреплены собственные данные.
  • [in] native_object: Собственные данные, которые будут прикреплены к объекту JavaScript.
  • [in] finalize_cb: Собственный обратный вызов, который будет использоваться для освобождения собственных данных, когда объект JavaScript готов для сборки мусора. napi_finalize предоставляет более подробную информацию.
  • [in] finalize_hint: Необязательная контекстная подсказка, которая передается в обратный вызов finalize.
  • [out] result: Необязательная ссылка на объект JavaScript.

Возврат napi_ok если API удалось.

Добавляет napi_finalize обратный вызов, который будет вызываться, когда объект JavaScript в js_object готов к вывозу мусора. Этот API похож на napi_wrap() Кроме этого:

  • собственные данные не могут быть получены позже с помощью napi_unwrap(),
  • и его нельзя удалить позже, используя napi_remove_wrap(), а также
  • API можно вызывать несколько раз с разными элементами данных, чтобы прикрепить каждый из них к объекту JavaScript, и
  • объект, которым управляет API, может использоваться с napi_wrap().

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

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

Модули аддонов часто должны использовать асинхронные помощники из 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 в обратном вызове execute, поскольку он, скорее всего, выполнит 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);

Когда эти методы вызываются, data переданный параметр будет предоставлен аддоном void* данные, которые были переданы в napi_create_async_work вызов.

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

napi_status napi_queue_async_work(napi_env env,
                                  napi_async_work work);

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

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

napi_create_async_work

napi_status napi_create_async_work(napi_env env,
                                   napi_value async_resource,
                                   napi_value async_resource_name,
                                   napi_async_execute_callback execute,
                                   napi_async_complete_callback complete,
                                   void* data,
                                   napi_async_work* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] async_resource: Необязательный объект, связанный с асинхронной работой, который будет передан возможному async_hooks init крючки.
  • [in] async_resource_name: Идентификатор типа ресурса, который предоставляется для диагностической информации, предоставляемой async_hooks API.
  • [in] execute: Собственная функция, которая должна быть вызвана для асинхронного выполнения логики. Данная функция вызывается из потока рабочего пула и может выполняться параллельно с основным потоком цикла событий.
  • [in] complete: Собственная функция, которая будет вызываться при завершении или отмене асинхронной логики. Данная функция вызывается из основного потока цикла событий. napi_async_complete_callback предоставляет более подробную информацию.
  • [in] data: Контекст данных, предоставляемых пользователем. Это будет передано обратно в функции execute и complete.
  • [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

napi_status napi_delete_async_work(napi_env env,
                                   napi_async_work work);
  • [in] env: Среда, в которой вызывается API.
  • [in] work: Дескриптор, возвращаемый вызовом napi_create_async_work.

Возврат napi_ok если API удалось.

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

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

napi_queue_async_work

napi_status napi_queue_async_work(napi_env env,
                                  napi_async_work work);
  • [in] env: Среда, в которой вызывается API.
  • [in] work: Дескриптор, возвращаемый вызовом napi_create_async_work.

Возврат napi_ok если API удалось.

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

napi_cancel_async_work

napi_status napi_cancel_async_work(napi_env env,
                                   napi_async_work work);
  • [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

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

Возврат napi_ok если API удалось.

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

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

napi_async_destroy

napi_status napi_async_destroy(napi_env env,
                               napi_async_context async_context);
  • [in] env: Среда, в которой вызывается API.
  • [in] async_context: Асинхронный контекст, который нужно уничтожить.

Возврат napi_ok если API удалось.

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

napi_make_callback

NAPI_EXTERN napi_status napi_make_callback(napi_env env,
                                           napi_async_context async_context,
                                           napi_value recv,
                                           napi_value func,
                                           size_t argc,
                                           const napi_value* argv,
                                           napi_value* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] async_context: Контекст для асинхронной операции, вызывающей обратный вызов. Обычно это значение, полученное ранее из napi_async_init. Чтобы сохранить совместимость ABI с предыдущими версиями, передавая NULL для async_context не приводит к ошибке. Однако это приводит к некорректной работе асинхронных хуков. Возможные проблемы включают потерю асинхронного контекста при использовании AsyncLocalStorage API.
  • [in] recv: The this значение, переданное вызываемой функции.
  • [in] func: napi_value представляющий вызываемую функцию JavaScript.
  • [in] argc: Количество элементов в argv множество.
  • [in] argv: Массив значений JavaScript как napi_value представляющие аргументы функции.
  • [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.nextTicks или обещания, запланированные в очереди микрозадач JavaScript во время обратного вызова, выполняются перед возвратом в C / C ++.

napi_open_callback_scope

NAPI_EXTERN napi_status napi_open_callback_scope(napi_env env,
                                                 napi_value resource_object,
                                                 napi_async_context context,
                                                 napi_callback_scope* result)
  • [in] env: Среда, в которой вызывается API.
  • [in] 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

NAPI_EXTERN napi_status napi_close_callback_scope(napi_env env,
                                                  napi_callback_scope scope)
  • [in] env: Среда, в которой вызывается API.
  • [in] scope: Область, которую необходимо закрыть.

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

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

napi_get_node_version

typedef struct {
  uint32_t major;
  uint32_t minor;
  uint32_t patch;
  const char* release;
} napi_node_version;

napi_status napi_get_node_version(napi_env env,
                                  const napi_node_version** version);
  • [in] env: Среда, в которой вызывается API.
  • [out] version: Указатель на информацию о версии самого Node.js.

Возврат napi_ok если API удалось.

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

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

napi_get_version

napi_status napi_get_version(napi_env env,
                             uint32_t* result);
  • [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

NAPI_EXTERN napi_status napi_adjust_external_memory(napi_env env,
                                                    int64_t change_in_bytes,
                                                    int64_t* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] change_in_bytes: Изменение выделенной извне памяти, которая поддерживается объектами JavaScript.
  • [out] result: Скорректированное значение

Возврат napi_ok если API удалось.

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

Обещания

Node-API предоставляет возможности для создания Promise объекты, как описано в Раздел 25.4 спецификации ECMA. Он реализует обещания как пару объектов. Когда обещание создается napi_create_promise(), создается "отложенный" объект, который возвращается вместе с Promise. Отложенный объект привязан к созданному Promise и это единственный способ решить или отклонить Promise с использованием napi_resolve_deferred() или napi_reject_deferred(). Отложенный объект, созданный napi_create_promise() освобожден napi_resolve_deferred() или napi_reject_deferred(). В Promise объект может быть возвращен в JavaScript, где его можно использовать обычным образом.

Например, чтобы создать обещание и передать его асинхронному исполнителю:

napi_deferred deferred;
napi_value promise;
napi_status status;

// Create the promise.
status = napi_create_promise(env, &deferred, &promise);
if (status != napi_ok) return NULL;

// Pass the deferred to a function that performs an asynchronous action.
do_something_asynchronous(deferred);

// Return the promise to JS
return promise;

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

napi_deferred deferred;
napi_value undefined;
napi_status status;

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

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

// At this point the deferred has been freed, so we should assign NULL to it.
deferred = NULL;

napi_create_promise

napi_status napi_create_promise(napi_env env,
                                napi_deferred* deferred,
                                napi_value* promise);
  • [in] env: Среда, в которой вызывается API.
  • [out] deferred: Вновь созданный отложенный объект, который позже может быть передан в napi_resolve_deferred() или napi_reject_deferred() решить соотв. отклонить связанное обещание.
  • [out] promise: Обещание JavaScript, связанное с отложенным объектом.

Возврат napi_ok если API удалось.

Этот API создает отложенный объект и обещание JavaScript.

napi_resolve_deferred

napi_status napi_resolve_deferred(napi_env env,
                                  napi_deferred deferred,
                                  napi_value resolution);
  • [in] env: Среда, в которой вызывается API.
  • [in] deferred: Отложенный объект, связанный с которым обещание разрешить.
  • [in] resolution: Значение, с которым разрешается обещание.

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

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

napi_reject_deferred

napi_status napi_reject_deferred(napi_env env,
                                 napi_deferred deferred,
                                 napi_value rejection);
  • [in] env: Среда, в которой вызывается API.
  • [in] deferred: Отложенный объект, связанный с которым обещание разрешить.
  • [in] rejection: Значение, с которым следует отклонить обещание.

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

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

napi_is_promise

napi_status napi_is_promise(napi_env env,
                            napi_value value,
                            bool* is_promise);
  • [in] env: Среда, в которой вызывается API.
  • [in] value: Значение для изучения
  • [out] is_promise: Флаг, указывающий, promise - это собственный объект обещания (то есть объект обещания, созданный базовым механизмом).

Выполнение скрипта

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

napi_run_script

NAPI_EXTERN napi_status napi_run_script(napi_env env,
                                        napi_value script,
                                        napi_value* result);
  • [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

NAPI_EXTERN napi_status napi_get_uv_event_loop(napi_env env,
                                               struct uv_loop_s** loop);
  • [in] env: Среда, в которой вызывается API.
  • [out] loop: Текущий экземпляр цикла libuv.

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

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

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

Эти API предоставляют тип napi_threadsafe_function а также API для создания, уничтожения и вызова объектов этого типа. napi_create_threadsafe_function() создает постоянную ссылку на napi_value который содержит функцию JavaScript, которую можно вызывать из нескольких потоков. Вызовы происходят асинхронно. Это означает, что значения, с которыми должен быть вызван обратный вызов JavaScript, будут помещены в очередь, и для каждого значения в очереди в конечном итоге будет выполнен вызов функции JavaScript.

При создании napi_threadsafe_function а napi_finalize обратный звонок может быть предоставлен. Этот обратный вызов будет вызываться в основном потоке, когда потокобезопасная функция вот-вот будет уничтожена. Он получает контекст и данные финализации, предоставленные во время построения, и предоставляет возможность для очистки после потоков, например. позвонив uv_thread_join(). За исключением потока основного цикла, потоки не должны использовать потокобезопасную функцию после завершения обратного вызова finalize.

В context данный во время звонка napi_create_threadsafe_function() может быть получен из любого потока с помощью вызова napi_get_threadsafe_function_context().

Вызов поточно-ориентированной функции

napi_call_threadsafe_function() может использоваться для инициирования вызова в JavaScript. napi_call_threadsafe_function() принимает параметр, который определяет, будет ли API вести себя блокирующим образом. Если установлено на napi_tsfn_nonblocking, API ведет себя неблокирующе, возвращая napi_queue_full если очередь была заполнена, что препятствует успешному добавлению данных в очередь. Если установлено на napi_tsfn_blocking, API блокируется до тех пор, пока в очереди не станет доступным место. napi_call_threadsafe_function() никогда не блокируется, если потокобезопасная функция была создана с максимальным размером очереди 0.

napi_call_threadsafe_function() не следует называть napi_tsfn_blocking из потока JavaScript, потому что, если очередь заполнена, это может вызвать взаимоблокировку потока JavaScript.

Фактический вызов в JavaScript контролируется обратным вызовом, заданным через call_js_cb параметр. call_js_cb вызывается в основном потоке один раз для каждого значения, которое было помещено в очередь в результате успешного вызова napi_call_threadsafe_function(). Если такой обратный вызов не задан, будет использоваться обратный вызов по умолчанию, и результирующий вызов JavaScript не будет иметь аргументов. В call_js_cb обратный вызов получает функцию JavaScript для вызова как napi_value по своим параметрам, а также void* указатель контекста, используемый при создании napi_threadsafe_functionи следующий указатель данных, созданный одним из вторичных потоков. Затем обратный вызов может использовать API, например napi_call_function() для вызова JavaScript.

Обратный вызов также может быть вызван с помощью env а также call_js_cb оба установлены на NULL чтобы указать, что вызовы JavaScript больше невозможны, а в очереди остаются элементы, которые, возможно, необходимо освободить. Обычно это происходит, когда процесс Node.js завершается, в то время как потокобезопасная функция все еще активна.

Нет необходимости вызывать JavaScript через napi_make_callback() потому что Node-API работает call_js_cb в контексте, подходящем для обратных вызовов.

Подсчет ссылок поточно-ориентированных функций

Темы можно добавлять и удалять из napi_threadsafe_function объект за время его существования. Таким образом, помимо указания начального количества потоков при создании, napi_acquire_threadsafe_function может быть вызван, чтобы указать, что новый поток начнет использовать потокобезопасную функцию. Сходным образом, napi_release_threadsafe_function может быть вызван, чтобы указать, что существующий поток перестанет использовать потокобезопасную функцию.

napi_threadsafe_function объекты уничтожаются, когда каждый поток, использующий объект, вызвал napi_release_threadsafe_function() или получил статус возврата napi_closing в ответ на звонок napi_call_threadsafe_function. Очередь очищается до napi_threadsafe_function уничтожен. napi_release_threadsafe_function() должен быть последним вызовом API, выполненным вместе с заданным napi_threadsafe_function, потому что после завершения вызова нет гарантии, что napi_threadsafe_function по-прежнему выделяется. По той же причине не используйте потокобезопасные функции после получения возвращаемого значения napi_closing в ответ на звонок napi_call_threadsafe_function. Данные, связанные с napi_threadsafe_function может быть освобожден в его napi_finalize обратный вызов, который был передан napi_create_threadsafe_function(). Параметр initial_thread_count из napi_create_threadsafe_function отмечает начальное количество получений потоковобезопасных функций вместо вызова napi_acquire_threadsafe_function несколько раз при создании.

Как только количество потоков, использующих napi_threadsafe_function достигает нуля, никакие другие потоки не могут начать использовать его, вызывая napi_acquire_threadsafe_function(). Фактически, все последующие вызовы API, связанные с ним, кроме napi_release_threadsafe_function(), вернет значение ошибки napi_closing.

Поточно-ориентированную функцию можно «прервать», задав значение napi_tsfn_abort к napi_release_threadsafe_function(). Это приведет к тому, что все последующие API, связанные с поточно-ориентированной функцией, кроме napi_release_threadsafe_function() возвращать napi_closing даже до того, как его счетчик ссылок достигнет нуля. Особенно, napi_call_threadsafe_function() вернусь napi_closing, тем самым сообщая потокам, что больше невозможно выполнять асинхронные вызовы поточно-ориентированной функции. Это можно использовать как критерий для завершения потока. При получении возвращаемого значения napi_closing из napi_call_threadsafe_function() поток не должен больше использовать потокобезопасную функцию, потому что больше не гарантируется его выделение.

Принятие решения о том, следует ли продолжать процесс

Подобно дескрипторам libuv, потокобезопасные функции могут иметь «ссылки» и «ссылки без ссылок». «Ссылочная» потокобезопасная функция заставит цикл событий в потоке, в котором он создан, оставаться активным до тех пор, пока потокобезопасная функция не будет уничтожена. Напротив, поточно-ориентированная функция "без ссылки" не предотвратит выход из цикла обработки событий. API napi_ref_threadsafe_function а также napi_unref_threadsafe_function существуют для этой цели.

Также не делает napi_unref_threadsafe_function пометить потокобезопасные функции как подлежащие уничтожению и не napi_ref_threadsafe_function предотвратить его разрушение.

napi_create_threadsafe_function

NAPI_EXTERN napi_status
napi_create_threadsafe_function(napi_env env,
                                napi_value func,
                                napi_value async_resource,
                                napi_value async_resource_name,
                                size_t max_queue_size,
                                size_t initial_thread_count,
                                void* thread_finalize_data,
                                napi_finalize thread_finalize_cb,
                                void* context,
                                napi_threadsafe_function_call_js call_js_cb,
                                napi_threadsafe_function* result);
  • [in] env: Среда, в которой вызывается API.
  • [in] func: Необязательная функция JavaScript для вызова из другого потока. Он должен быть предоставлен, если NULL передается call_js_cb.
  • [in] async_resource: Необязательный объект, связанный с асинхронной работой, который будет передан возможному async_hooks init крючки.
  • [in] async_resource_name: Строка JavaScript для предоставления идентификатора типа ресурса, предоставляемого для диагностической информации, предоставляемой async_hooks API.
  • [in] max_queue_size: Максимальный размер очереди. 0 без ограничений.
  • [in] initial_thread_count: Начальное количество захватов, то есть начальное количество потоков, включая основной поток, которые будут использовать эту функцию.
  • [in] thread_finalize_data: Необязательные данные для передачи в thread_finalize_cb.
  • [in] thread_finalize_cb: Дополнительная функция для вызова, когда napi_threadsafe_function разрушается.
  • [in] context: Необязательные данные для присоединения к результирующему napi_threadsafe_function.
  • [in] call_js_cb: Необязательный обратный вызов, который вызывает функцию JavaScript в ответ на вызов в другом потоке. Этот обратный вызов будет вызываться в основном потоке. Если не указан, функция JavaScript будет вызываться без параметров и с undefined как его this ценить. napi_threadsafe_function_call_js предоставляет более подробную информацию.
  • [out] result: Асинхронная поточно-ориентированная функция JavaScript.

napi_get_threadsafe_function_context

NAPI_EXTERN napi_status
napi_get_threadsafe_function_context(napi_threadsafe_function func,
                                     void** result);
  • [in] func: Поточно-ориентированная функция, для которой нужно получить контекст.
  • [out] result: Место для хранения контекста.

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

napi_call_threadsafe_function

NAPI_EXTERN napi_status
napi_call_threadsafe_function(napi_threadsafe_function func,
                              void* data,
                              napi_threadsafe_function_call_mode is_blocking);
  • [in] func: Вызываемая асинхронная поточно-ориентированная функция JavaScript.
  • [in] 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

NAPI_EXTERN napi_status
napi_acquire_threadsafe_function(napi_threadsafe_function func);
  • [in] func: Асинхронная поточно-ориентированная функция JavaScript, которую нужно начать использовать.

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

Этот API может быть вызван из любого потока, который начнет использовать func.

napi_release_threadsafe_function

NAPI_EXTERN napi_status
napi_release_threadsafe_function(napi_threadsafe_function func,
                                 napi_threadsafe_function_release_mode mode);
  • [in] func: Асинхронная поточно-ориентированная функция JavaScript, счетчик ссылок которой подлежит уменьшению.
  • [in] 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

NAPI_EXTERN napi_status
napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func);
  • [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

NAPI_EXTERN napi_status
napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func);
  • [in] env: Среда, в которой вызывается API.
  • [in] func: Поточно-ориентированная функция без ссылки.

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

Этот API можно вызывать только из основного потока.

Разные утилиты

node_api_get_module_file_name

Стабильность: 1 - экспериментальная

NAPI_EXTERN napi_status
node_api_get_module_file_name(napi_env env, const char** result);
  • [in] env: Среда, в которой вызывается API.
  • [out] result: URL-адрес, содержащий абсолютный путь к месту, из которого была загружена надстройка. Для файла в локальной файловой системе он будет начинаться с file://. Строка заканчивается нулем и принадлежит env и поэтому не должны быть изменены или освобождены.

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