N-API
N-API (произносится как N, затем API) — это API для создания нативных дополнений. Оно независимо от основного JavaScript-движка (например, V8) и поддерживается в рамках самого Node.js. Это API будет иметь стабильный Application Binary Interface (ABI) в разных версиях Node.js. Оно предназначено для изоляции дополнений от изменений в подлежащем JavaScript-движке и позволяет модулям, скомпилированным для одной версии, работать в последующих версиях Node.js без перекомпиляции.
Дополнения строятся/упаковываются с тем же подходом/инструментами, которые описаны в разделе, озаглавленном C++ Дополнения. Единственное отличие — набор API, используемых нативным кодом. Вместо использования V8 или Native Abstractions for Node.js API используются функции, доступные в N-API.
API, экспонируемые N-API, как правило, используются для создания и манипулирования JavaScript-значениями. Концепции и операции, как правило, соответствуют идеям, указанным в спецификации языка ECMA262. У API есть следующие свойства:
- Все вызовы N-API возвращают код состояния типа
napi_status. Это состояние указывает на то, выполнен ли вызов API успешно или нет. - Значение возврата API передаётся через параметр вывода.
- Все JavaScript-значения абстрагированы за помощью непрозрачного типа, названного
napi_value. - В случае кода состояния ошибки дополнительную информацию можно получить, используя
napi_get_last_error_info. Дополнительную информацию можно найти в разделе об обработке ошибок Обработка ошибок.
Документация для N-API структурирована следующим образом:
- Основные типы данных N-API
- Обработка ошибок
- Управление жизненным циклом объектов
- Регистрация модулей
- Работа со значениями JavaScript
- Работа со значениями JavaScript — абстрактные операции
- Работа со свойствами JavaScript
- Работа с JavaScript-функциями
- Обёртка объекта
- Простые асинхронные операции
- Настраиваемые асинхронные операции
- Обещания
- Выполнение скрипта
N-API — это C-API, гарантирующий стабильность ABI в разных версиях Node.js и разных уровнях компилятора. Однако мы также понимаем, что C++ API может быть проще в использовании во многих случаях. Чтобы поддержать эти случаи, мы ожидаем наличия одного или нескольких C++ модулей-обёрток, которые обеспечивают инлайновый C++ API. Бинарные файлы, созданные с помощью этих модулей-обёрток, будут зависеть от символов функций N-API на основе C, экспортированных Node.js. Эти обёртки не являются частью N-API и не будут поддерживаться в рамках Node.js. Один из таких примеров: node-addon-api.
Использование
Для использования функций N-API включите файл node_api.h, который находится в каталоге src в дереве разработки Node. Например:
#include <node_api.h>
Это позволит использовать по умолчанию NAPI_VERSION для данной версии Node.js. Для обеспечения совместимости со специфическими версиями N-API, версию можно указать явно при включении заголовка:
#define NAPI_VERSION 3 #include <node_api.h>
Это ограничивает поверхность N-API только функциональностью, которая была доступна в указанных (и более ранних) версиях.
Некоторые части поверхности N-API считаются экспериментальными и требуют явного разрешения для доступа к этим API:
#define NAPI_EXPERIMENTAL #include <node_api.h>
В этом случае вся поверхность API, включая любые экспериментальные API, будет доступна коду модуля.
Матрица версий N-API
| 1 | 2 | 3 | |
|---|---|---|---|
| v4.x | |||
| v6.x | v6.14.2* | ||
| v8.x | v8.0.0* | v8.10.0* | |
| v9.x | v9.0.0* | v9.3.0* | v9.11.0* |
| v10.x | v10.0.0 |
* Указывает, что версия N-API была выпущена как экспериментальная
Основные типы данных N-API
N-API предоставляет следующие базовые типы данных в качестве абстракций, используемых различными API. Эти API следует рассматривать как непрозрачные, интроспектируемые только с помощью других вызовов N-API.
napi_status
Целочисленный код состояния, указывающий на успех или неудачу вызова N-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,
#ifdef NAPI_EXPERIMENTAL
napi_queue_full,
napi_closing,
#endif // NAPI_EXPERIMENTAL
} 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, содержащая VM-нейтральное описание ошибки. -
engine_reserved: Зарезервировано для VM-специфичных деталей ошибки. В настоящее время не реализовано ни для одного VM. -
engine_error_code: VM-специфический код ошибки. В настоящее время не реализовано ни для одного VM. -
error_code: Код состояния N-API, возникший при последней ошибке.
См. раздел Обработка ошибок для дополнительной информации.
napi_env
napi_env используется для представления контекста, который подлежащая реализация N-API может использовать для сохранения VM-специфического состояния. Эта структура передаётся нативным функциям при их вызове, и её необходимо передавать обратно при выполнении вызовов N-API. Конкретно, тот же napi_env, что и при первоначальном вызове нативной функции, должен передаваться всем последующим вложенным вызовам N-API. Кэширование napi_env для целей общего повторного использования запрещено.
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;
Типы управления памятью N-API
napi_handle_scope
Это абстракция, используемая для управления и изменения срока жизни объектов, созданных в определённом контексте. Как правило, значения N-API создаются в контексте области видимости управления обработкой. Когда нативная функция вызывается из JavaScript, существует область видимости управления обработкой по умолчанию. Если пользователь явно не создаёт новую область видимости управления обработкой, значения N-API будут созданы в области видимости управления обработкой по умолчанию. Для любых вызовов кода за пределами выполнения нативной функции (например, во время вызова обратного вызова libuv) модуль должен создать область видимости перед вызовом любых функций, которые могут привести к созданию JavaScript-значений.
Области видимости управления обработкой создаются с помощью napi_open_handle_scope и уничтожаются с помощью napi_close_handle_scope. Закрытие области видимости может указать сборщику мусора, что все napi_value, созданные в течение срока жизни области видимости управления обработкой, больше не ссылаются из текущей области стека.
Для получения более подробной информации см. раздел Управление жизненным циклом объектов.
napi_escapable_handle_scope
Области видимости с возможностью возврата — это специальный тип области видимости для возврата значений, созданных в определённой области видимости, в родительскую область видимости.
napi_ref
Это абстракция, используемая для ссылки на napi_value. Это позволяет пользователям управлять сроком жизни JavaScript-значений, включая явное определение их минимального срока жизни.
Для получения более подробной информации см. раздел Управление жизненным циклом объектов.
Типы обратных вызовов N-API
napi_callback_info
Непрозрачный тип данных, передаваемый функции обратного вызова. Он может использоваться для получения дополнительной информации о контексте, в котором был вызван обратный вызов.
napi_callback
Тип указателя на функцию для пользовательских нативных функций, которые должны быть экспонированы JavaScript через N-API. Функции обратного вызова должны удовлетворять следующей сигнатуре:
typedef napi_value (*napi_callback)(napi_env, napi_callback_info);
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);
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.
N-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может потребоваться освободить. -
[in] context: Необязательные данные, с которыми была создана функция, безопасная для потоков. -
[in] data: Данные, созданные дополнительным потоком. Функция обратного вызова должна преобразовать эти данные в значения JavaScript (с функциями N-API), которые можно передавать в качестве параметров при вызовеjs_callback. Этот указатель полностью управляется потоками и этой функцией обратного вызова. Таким образом, эта функция обратного вызова должна освободить данные.
Обработка ошибок
N-API использует как значения возврата, так и исключения JavaScript для обработки ошибок. Следующие разделы объясняют подход для каждого случая.
Значения возврата
Все функции N-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: Код состояния n-api для последней ошибки.
napi_get_last_error_info возвращает информацию о последнем вызове N-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: Структураnapi_extended_error_infoс дополнительной информацией об ошибке.
Возвращает napi_ok, если API успешно выполнена.
Этот API получает структуру napi_extended_error_info с информацией о последней произошедшей ошибке.
Примечание: Содержимое возвращаемой структуры napi_extended_error_info является допустимым только до тех пор, пока функция n-api не вызвана в той же среде env.
Примечание: Не полагайтесь на содержимое или формат расширенной информации, поскольку он не подлежит SemVer и может измениться в любое время. Он предназначен только для целей протоколирования.
Этот API может быть вызван даже если ожидается исключение JavaScript.
Исключения
Любой вызов функции N-API может привести к ожидающему исключению JavaScript. Это очевидно для любой функции, которая может вызвать выполнение JavaScript, но N-API указывает, что исключение может ожидаться по возвращении из любой функции API.
Если значение napi_status, возвращаемое функцией, равно napi_ok, то исключение не ожидается, и дополнительные действия не требуются. Если возвращаемое значение napi_status отличается от napi_ok или napi_pending_exception, то для восстановления и продолжения вместо простого немедленного возврата необходимо вызвать napi_is_exception_pending, чтобы определить, ожидается ли исключение.
Когда ожидается исключение, можно использовать один из двух подходов.
Первый подход заключается в выполнении необходимой очистки, а затем возврате, чтобы выполнение вернулось в JavaScript. В рамках возврата в JavaScript исключение будет брошено в точке в коде JavaScript, где была вызвана нативная функция. Поведение большинства вызовов N-API не определено, пока ожидается исключение, и многие просто вернут napi_pending_exception, поэтому важно сделать как можно меньше действий и затем вернуться в JavaScript, где исключение может быть обработано.
Второй подход заключается в попытке обработать исключение. В некоторых случаях нативный код может перехватить исключение, принять соответствующие действия и продолжить. Это рекомендуется только в определенных случаях, когда известно, что исключение можно безопасно обработать. В этих случаях можно использовать napi_get_and_clear_last_exception для получения и очистки исключения. При успехе результат будет содержать обработку последнего брошенного JavaScript-объекта. Если после получения исключения оказывается, что исключение все же нельзя обработать, его можно повторно бросить с помощью napi_throw, где error – объект JavaScript Error, который необходимо бросить.
Следующие вспомогательные функции также доступны в случае, если нативный код должен бросить исключение или определить, является ли 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. где result – napi_value, который ссылается на недавно созданный объект JavaScript Error.
Проект Node.js добавляет коды ошибок ко всем ошибкам, генерируемым внутри. Цель состоит в том, чтобы приложения использовали эти коды ошибок для проверки всех ошибок. Сопутствующие сообщения об ошибках остаются, но используются только для протоколирования и отображения с ожиданием, что сообщение может измениться без применения SemVer. Для поддержки этой модели в N-API, как в внутренней функциональности, так и для функциональности конкретных модулей (так как это хорошая практика), функции throw_ и create_ принимают необязательный параметр code, который является строкой кода, который необходимо добавить к объекту ошибки. Если необязательный параметр равен NULL, код не будет связан с ошибкой. Если код предоставлен, имя, связанное с ошибкой, также обновляется следующим образом:
originalName [code]
где originalName – исходное имя, связанное с ошибкой, а code – код, который был предоставлен. Например, если код – 'ERR_ERROR_1', и создается TypeError, то имя будет:
TypeError [ERR_ERROR_1]
napi_throw
NODE_EXTERN napi_status napi_throw(napi_env env, napi_value error);
-
[in] env: Среда, в которой вызывается API. -
[in] error: napi_value для объекта Error, который нужно бросить.
Возвращает napi_ok, если API выполнена успешно.
Этот API бросает предоставленный объект JavaScript Error.
napi_throw_error
NODE_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
NODE_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 выполнена успешно.
napi_throw_range_error
NODE_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
NODE_EXTERN napi_status napi_is_error(napi_env env,
napi_value value,
bool* result);
-
[in] env: Среда, в которой вызывается API. -
[in] msg:napi_value, который нужно проверить. -
[out] result: Булево значение, установленное в true, еслиnapi_valueпредставляет ошибку, и в false в противном случае.
Возвращает napi_ok, если API выполнилось успешно.
Этот API запрашивает napi_value, чтобы проверить, представляет ли он объект ошибки.
napi_create_error
NODE_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со строкой для кода ошибки, чтобыbe associated with the error.
-
[in] msg: napi_value, ссылающийся на JavaScript-строку, используемую в качестве сообщения об ошибке. -
[out] result:napi_value, представляющий созданную ошибку.
Возвращает napi_ok, если API выполнилось успешно.
Этот API возвращает JavaScript-ошибку с указанным текстом.
napi_create_type_error
NODE_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со строкой для кода ошибки, чтобыbe associated with the error.
-
[in] msg: napi_value, ссылающийся на JavaScript-строку, используемую в качестве сообщения об ошибке. -
[out] result:napi_value, представляющий созданную ошибку.
Возвращает napi_ok, если API выполнилось успешно.
Этот API возвращает JavaScript TypeError с предоставленным текстом.
napi_create_range_error
NODE_EXTERN napi_status napi_create_range_error(napi_env env,
napi_value code,
const char* msg,
napi_value* result);
-
[in] env: Среда, в которой вызывается API. -
[in] code: Необязательныйnapi_valueсо строкой для кода ошибки, чтобыbe associated with the error.
-
[in] msg: napi_value, ссылающийся на JavaScript-строку, используемую в качестве сообщения об ошибке. -
[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 возвращает true, если исключение ожидается.
Этот 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 возвращает true, если ожидается исключение.
Этот 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-исключение.
Управление жизненным циклом объектов
При выполнении вызовов N-API могут возвращаться ссылки на объекты в куче для базовой виртуальной машины в виде napi_values. Эти ссылки должны удерживать объекты "живыми" до тех пор, пока они больше не нужны коду нативного языка, в противном случае объекты могут быть собраны сборщиком мусора до того, как код нативного языка закончит их использование.
При возвращении ссылок на объекты они связываются с "областью видимости". Жизненный цикл по умолчанию связан с жизненным циклом вызова метода нативного языка. В результате по умолчанию ссылки остаются действительными, и объекты, связанные с этими ссылками, будут удерживаться живыми в течение всего жизненного цикла вызова метода нативного языка.
Однако во многих случаях необходимо, чтобы ссылки оставались действительными в течение более короткого или более длительного срока, чем срок действия метода нативного языка. В последующих разделах описаны функции N-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
}
Это приведет к созданию большого количества ссылок, потребляющих значительные ресурсы. Кроме того, даже если код нативного языка мог использовать только самую последнюю ссылку, все связанные объекты также будут удерживаться живыми, так как они все находятся в одной области видимости.
Для обработки этого случая N-API предоставляет возможность создания новой "области видимости", к которой будут привязаны вновь созданные ссылки. После того, как эти ссылки больше не нужны, область видимости может быть "закрыта", и все ссылки, связанные с областью видимости, будут аннулированы. Доступными методами открытия/закрытия областей видимости являются napi_open_handle_scope и napi_close_handle_scope.
N-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;
}
}
При вложенности областей видимости существуют случаи, когда ссылке из внутренней области видимости необходимо жить дольше, чем срок действия этой области видимости. N-API поддерживает "извлекаемую область видимости", чтобы обработать такой случай. Извлекаемая область видимости позволяет одной ссылке "перейти" во внешнюю область видимости, так что срок действия ссылки меняется с текущей области видимости на внешнюю.
Доступными методами открытия/закрытия извлекаемых областей видимости являются napi_open_escapable_handle_scope и napi_close_escapable_handle_scope.
Запрос на продвижение ссылки выполняется через napi_escape_handle, который можно вызывать только один раз.
napi_open_handle_scope
NODE_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
NODE_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
NODE_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
NODE_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-объект, который нужно обработать. -
[out] result:napi_value, представляющий дескриптор обработанного объекта во внешнем контексте.
Возвращает napi_ok, если API выполнилась успешно.
Этот API повышает приоритет дескриптора JavaScript-объекта, чтобы он оставался действительным на протяжении всего существования внешнего контекста. Его можно вызывать только один раз в рамках одного контекста. При повторном вызове будет возвращено сообщение об ошибке.
Этот API может быть вызван даже при наличии ожидающей JavaScript-исключительной ситуации.
Ссылки на объекты с продолжительностью жизни, превышающей продолжительность жизни собственного метода
В некоторых случаях дополнение должно иметь возможность создавать и ссылаться на объекты с продолжительностью жизни, превышающей продолжительность жизни одного вызова собственного метода. Например, для создания конструктора и последующего использования этого конструктора в запросе на создание экземпляров необходимо иметь возможность ссылаться на объект конструктора в нескольких запросах на создание экземпляров. Это было бы невозможно с обычным дескриптором, возвращаемым как napi_value, как описано в предыдущем разделе. Продолжительность жизни обычного дескриптора управляется контекстами, и все контексты должны быть закрыты перед окончанием собственного метода.
N-API предоставляет методы для создания постоянных ссылок на объект. Каждая постоянная ссылка имеет связанный счётчик со значением 0 или больше. Счётчик определяет, будет ли ссылка сохранять соответствующий объект живым. Ссылки со значением счётчика 0 не препятствуют сбору мусора объекта и часто называются «слабыми» ссылками. Любое значение счётчика, большее 0, предотвратит сбор мусора объекта.
Ссылки могут быть созданы с начальным значением счётчика ссылок. Затем счётчик можно изменить с помощью napi_reference_ref и napi_reference_unref. Если объект собран, в то время как счётчик ссылки равен 0, все последующие вызовы получения объекта, связанного со ссылкой napi_get_reference_value, вернут NULL для возвращаемого napi_value. Попытка вызвать napi_reference_ref для ссылки, объект которой был собран, приведёт к ошибке.
Ссылки должны быть удалены, когда они больше не нужны дополнению. После удаления ссылки она больше не будет препятствовать сбору мусора соответствующего объекта. Отсутствие удаления постоянной ссылки приведёт к утечке памяти, при которой как собственная память для постоянной ссылки, так и соответствующий объект в куче будут сохраняться навсегда.
Можно создать несколько постоянных ссылок, которые ссылаются на один и тот же объект, каждая из которых либо сохраняет объект живым, либо нет, в зависимости от её собственного счётчика.
napi_create_reference
NODE_EXTERN napi_status napi_create_reference(napi_env env,
napi_value value,
int initial_refcount,
napi_ref* result);
-
[in] env: Окружение, в котором вызывается API. -
[in] value:napi_value, представляющий объект, для которого требуется ссылка. -
[in] initial_refcount: Начальный счётчик ссылок для новой ссылки. -
[out] result:napi_ref, указывающий на новую ссылку.
Возвращает napi_ok, если API выполнилась успешно.
Этот API создаёт новую ссылку со значением счётчика ссылок, указанным в параметре, на объект, переданный в качестве параметра.
napi_delete_reference
NODE_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
NODE_EXTERN napi_status napi_reference_ref(napi_env env,
napi_ref ref,
int* result);
-
[in] env: Окружение, в котором вызывается API. -
[in] ref:napi_ref, для которого счётчик ссылок будет увеличен. -
[out] result: Новое значение счётчика ссылок.
Возвращает napi_ok, если API выполнилась успешно.
Этот API увеличивает счётчик ссылок для переданной ссылки и возвращает полученное значение счётчика.
napi_reference_unref
NODE_EXTERN napi_status napi_reference_unref(napi_env env,
napi_ref ref,
int* result);
-
[in] env: Окружение, в котором вызывается API. -
[in] ref:napi_ref, для которого счётчик ссылок будет уменьшен. -
[out] result: Новое значение счётчика ссылок.
Возвращает napi_ok, если API выполнилась успешно.
Этот API уменьшает счётчик ссылок для переданной ссылки и возвращает полученное значение счётчика.
napi_get_reference_value
NODE_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, для которого запрашивается соответствующий объект. -
[out] result:napi_valueдля объекта, на который ссылаетсяnapi_ref.
Возвращает napi_ok, если API выполнилась успешно.
Если ссылка всё ещё действительна, этот API возвращает napi_value, представляющий JavaScript-объект, связанный с napi_ref. В противном случае результат будет NULL.
Очистка при завершении текущей инстанции Node.js
Хотя процесс Node.js обычно освобождает все свои ресурсы при завершении, разработчики Node.js или будущая поддержка Worker могут потребовать от дополнений регистрации обработчиков очистки, которые будут выполнены после завершения текущей инстанции Node.js.
N-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_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, в противном случае процесс завершится аварийно.
Регистрация модулей
Модули N-API регистрируются аналогично другим модулям, за исключением того, что вместо использования макроса NODE_MODULE используется следующее:
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
Следующее отличие — сигнатура метода Init. Для модуля N-API она выглядит следующим образом:
napi_value Init(napi_env env, napi_value exports);
Значение, возвращаемое из Init, рассматривается как объект exports для модуля. Методу Init передаётся пустой объект через параметр exports для удобства. Если Init возвращает NULL, параметр, переданный в качестве exports, экспортируется модулем. Модули N-API не могут изменять объект module, но могут указать что угодно в качестве свойства exports модуля.
Например, чтобы добавить метод hello в качестве функции, чтобы его можно было вызывать в качестве метода, предоставляемого дополнением:
napi_value Init(napi_env env, napi_value exports) {
napi_status status;
napi_property_descriptor desc =
{"hello", Method, 0, 0, 0, napi_default, 0};
if (status != napi_ok) return 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;
}
Например, чтобы определить класс, для того чтобы можно было создавать новые экземпляры (часто используется с Object Wrap):
// NOTE: partial example, not all referenced code is included
napi_value Init(napi_env env, napi_value exports) {
napi_status status;
napi_property_descriptor properties[] = {
{ "value", NULL, GetValue, SetValue, 0, napi_default, 0 },
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;
}
Дополнительные сведения о настройке свойств объектов см. в разделе Работа со свойствами JavaScript.
Дополнительные сведения о построении модулей дополнений см. в существующей API
Работа со значениями JavaScript
N-API предоставляет набор API для создания всех типов значений JavaScript. Некоторые из этих типов описаны в разделе 6 спецификации языка ECMAScript.
В основе этих API лежит одно из следующих действий:
- Создание нового JavaScript-объекта
- Преобразование из примитивного типа C в значение N-API
- Преобразование из значения N-API в примитивный тип C
- Получение глобальных экземпляров, включая
undefinedиnull
Значения N-API представлены типом napi_value. Любой вызов N-API, требующий значения JavaScript, принимает napi_value. В некоторых случаях API предварительно проверяет тип napi_value. Однако для повышения производительности лучше, чтобы вызывающая сторона гарантировала, что napi_value имеет ожидаемый тип JavaScript, соответствующий API.
Типы перечислений
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_valuetype;
Описывает тип napi_value. Обычно он соответствует типам, описанным в разделе 6.1 спецификации языка ECMAScript. В дополнение к типам в этом разделе napi_valuetype также может представлять функции и объекты с внешними данными.
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_typedarray_type;
Это представляет собой базовый двоичный скалярный тип данных TypedArray. Элементы этого перечисления соответствуют разделу 22.2 спецификации языка ECMAScript .
Функции создания объектов
napi_create_array
napi_status napi_create_array(napi_env env, napi_value* result)
-
[in] env: Окружение, в котором вызывается вызов N-API. -
[out] result: Anapi_valueпредставляющий массив JavaScript.
Возвращает napi_ok, если API выполнилось успешно.
Этот API возвращает значение N-API, соответствующее типу массива JavaScript. Массивы 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: Начальная длина массива. -
[out] result: Anapi_valueпредставляющий массив JavaScript.
Возвращает napi_ok, если API выполнилось успешно.
Этот API возвращает значение N-API, соответствующее типу массива JavaScript. Свойство 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: Anapi_valueпредставляющий буфер массива JavaScript.
Возвращает napi_ok, если API выполнилось успешно.
Этот API возвращает значение N-API, соответствующее буферу массива JavaScript. Буферы массивов используются для представления буферов двоичных данных фиксированной длины. Они обычно используются в качестве буфера-хранилища для объектов TypedArray. Выделенный буфер ArrayBuffer будет иметь подлежащий байтовый буфер, размер которого определяется параметром length. Подлежащий буфер по желанию возвращается вызывающей стороне, в случае если вызывающая сторона хочет напрямую манипулировать буфером. К этому буферу можно записывать напрямую только из кода нативных языков. Для записи в этот буфер из JavaScript нужно создать объект массива с типом или объект DataView.
Объекты ArrayBuffer JavaScript описаны в разделе 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: Anapi_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: Указатель на подлежащий буфер данных нового буфера. -
[out] result: Anapi_valueпредставляющийnode::Buffer.
Возвращает napi_ok, если API выполнилось успешно.
Этот API выделяет объект node::Buffer и инициализирует его данными, скопированными из переданного буфера. Хотя эта структура данных всё ещё полностью поддерживается, в большинстве случаев использование TypedArray будет достаточным.
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: Необязательный обратный вызов для вызова, когда внешнее значение собирается. -
[in] finalize_hint: Необязательное значение для передачи в обратный вызов finalize во время сбора. -
[out] result: Anapi_valueпредставляющий внешнее значение.
Возвращает napi_ok, если API выполнилось успешно.
Этот API выделяет значение JavaScript со связанными внешними данными. Это используется для передачи внешних данных через код JavaScript, чтобы их можно было получить позже кодом нативного языка. API позволяет вызывающей стороне передать обратный вызов finalize, если подлежащий ресурс нативного кода нужно очистить, когда внешнее значение JavaScript будет собрано.
Примечание: Создаваемое значение не является объектом и, следовательно, не поддерживает дополнительные свойства. Оно считается отдельным типом значения: вызов 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. -
[in] finalize_hint: Необязательное значение для передачи в обратный вызов finalize во время сбора. -
[out] result: Anapi_valueпредставляющий буфер массива JavaScript.
Возвращает napi_ok, если API выполнилось успешно.
Этот API возвращает значение N-API, соответствующее буферу массива JavaScript. Подлежащий байтовый буфер ArrayBuffer выделяется и управляется внешне. Вызывающая сторона должна гарантировать, что байтовый буфер остаётся валидным до тех пор, пока не будет вызван обратный вызов finalize.
Объекты ArrayBuffers JavaScript описаны в разделе 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: Необработанный указатель на подлежащий буфер для копирования. -
[in] finalize_cb: Необязательный обратный вызов для вызова при сборе ArrayBuffer. -
[in] finalize_hint: Необязательное значение для передачи в обратный вызов finalize во время сбора. -
[out] result: Anapi_valueпредставляющийnode::Buffer.
Возвращает napi_ok, если API выполнилось успешно.
Этот API выделяет объект node::Buffer и инициализирует его данными, поддерживаемыми переданным буфером. Хотя эта структура данных всё ещё полностью поддерживается, в большинстве случаев использование TypedArray будет достаточным.
Примечание: Для Node.js >=4 Buffers являются массивами Uint8.
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. -
[in] length: Длина utf8name в байтах, илиNAPI_AUTO_LENGTH, если она имеет нуль-терминатор. -
[in] cb: Указатель на функцию нативного языка, которая будет вызываться, когда созданная функция будет вызвана из JavaScript. -
[in] data: Необязательные произвольные данные контекста, которые будут передаваться в нативную функцию, когда она вызывается. -
[out] result: Anapi_valueпредставляющий функцию JavaScript.
Возвращает napi_ok, если API выполнилось успешно.
Этот API возвращает значение N-API, соответствующее объекту JavaScript Function. Он используется для обертывания нативных функций, чтобы их можно было вызывать из JavaScript.
Функции JavaScript описаны в разделе 19.2 спецификации языка ECMAScript.
napi_create_object
napi_status napi_create_object(napi_env env, napi_value* result)
-
[in] env: Окружение, в котором вызывается API. -
[out] result: Anapi_valueпредставляющий объект JavaScript.
Возвращает napi_ok, если API выполнилось успешно.
Этот API выделяет стандартный объект JavaScript. Это эквивалентно выполнению new Object() в JavaScript.
Тип объекта JavaScript описан в разделе 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, которая должна быть установлена в качестве описания для символа. -
[out] result: Anapi_valueпредставляющий символ JavaScript.
Возвращает napi_ok, если API выполнилось успешно.
Этот API создаёт объект JavaScript Symbol из UTF8-закодированной строки C.
Тип 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: Представляющий 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: Представляющий JavaScript DataView.
Возвращает napi_ok, если API выполнилось успешно.
Этот API создаёт объект JavaScript DataView над существующим ArrayBuffer. Объекты DataView предоставляют массивный вид на подлежащий буфер данных, но позволяют использовать элементы разного размера и типа в ArrayBuffer.
Требуется, чтобы byte_length + byte_offset было меньше или равно размеру в байтах переданного массива. Если нет, возникает исключение RangeError.
Объекты JavaScript DataView описаны в разделе 24.3 спецификации языка ECMAScript.
Функции преобразования из типов C в N-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: Представляющий 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: Представляющий 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: Представляющий 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: Представляющий JavaScript Number.
Возвращает napi_ok, если API выполнилось успешно.
Этот API используется для преобразования типа C double в тип JavaScript Number.
Тип JavaScript Number описан в разделе 6.1.6 спецификации языка ECMAScript.
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: Представляющий 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: Представляющий 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: Представляющий JavaScript String.
Возвращает napi_ok, если API выполнилось успешно.
Этот API создаёт объект JavaScript String из строки C в кодировке UTF8.
Тип JavaScript String описан в разделе 6.1.4 спецификации языка ECMAScript.
Функции преобразования из N-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: Представляющий JavaScript массив, длина которого запрашивается. -
[out] result: Представляющий длину массива.
Возвращает napi_ok, если API выполнилось успешно.
Этот API возвращает длину массива.
Длина массива описана в разделе 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: Представляющий ArrayBuffer, который запрашивается. -
[out] data: Базовый буфер данных ArrayBuffer. -
[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. -
[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.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: Буфер данных, лежащий в основе массива. -
[out] byte_offset: Смещение в байтах в буфере данных, с которого нужно начать отображение TypedArray.
Возвращает 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. -
[out] arraybuffer: ArrayBuffer, лежащий в основе DataView. -
[out] byte_offset: Смещение в байтах в буфере данных, с которого нужно начать отображение DataView.
Возвращает napi_ok, если API выполнено успешно.
Этот API возвращает различные свойства DataView.
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 булево значение. -
[out] result: Эквивалент C boolean исходного JavaScript булевого значения.
Возвращает napi_ok, если API выполнено успешно. Если передан небулевое napi_value, возвращается napi_boolean_expected.
Этот API возвращает эквивалент C boolean исходного JavaScript булевого значения.
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 числовое значение. -
[out] result: Эквивалент C double исходного JavaScript числового значения.
Возвращает napi_ok, если API выполнено успешно. Если передан нечисловое napi_value, возвращается napi_number_expected.
Этот API возвращает эквивалент C double исходного JavaScript числового значения.
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 числовое значение. -
[out] result: Эквивалент C int32 исходного JavaScript числового значения.
Возвращает napi_ok, если API выполнено успешно. Если передан нечисловое napi_value, возвращается napi_number_expected.
Если число выходит за пределы диапазона 32-битового целого числа, результат усекается до эквивалента нижних 32 бит. Это может привести к тому, что большое положительное число станет отрицательным, если значение превышает 2^31 -1.
Неконечные числовые значения (NaN, положительная или отрицательная бесконечность) устанавливают результат в ноль.
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 числовое значение. -
[out] result: Эквивалент C int64 исходного JavaScript числового значения.
Возвращает napi_ok, если API выполнено успешно. Если передан нечисловое napi_value, возвращается napi_number_expected.
Этот API возвращает эквивалент C int64 исходного JavaScript числового значения.
Числовые значения, выходящие за пределы диапазона Number.MIN_SAFE_INTEGER -(2^53 - 1) - Number.MAX_SAFE_INTEGER (2^53 - 1), потеряют точность.
Неконечные числовые значения (NaN, положительная или отрицательная бесконечность) устанавливают результат в ноль.
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, возвращается длина строки (в байтах). -
[in] bufsize: Размер буфера назначения. Если этого значения недостаточно, возвращаемая строка будет усечена. -
[out] result: Количество скопированных байтов в буфер, не включая нулевой терминатор.
Возвращает napi_ok, если API выполнено успешно. Если передан нестроковое 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, возвращается длина строки (в байтах). -
[in] bufsize: Размер буфера назначения. Если этого значения недостаточно, возвращаемая строка будет усечена. -
[out] result: Количество скопированных байтов в буфер, не включая нулевой терминатор.
Возвращает napi_ok, если API выполнено успешно. Если передан нестроковое 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 выполнено успешно. Если передан нестроковое 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 числовое значение. -
[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 возвращает глобальный объект.
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 Undefined.
Возвращает napi_ok, если API выполнилось успешно.
Этот API возвращает объект Undefined.
Работа со значениями JavaScript — Абстрактные операции
N-API предоставляет набор API для выполнения некоторых абстрактных операций со значениями JavaScript. Некоторые из этих операций описаны в разделе 7 спецификации языка ECMAScript.
Эти API поддерживают выполнение одного из следующих действий:
- Приведение значений JavaScript к определённым типам JavaScript (таким как Number или String)
- Проверка типа значения JavaScript
- Проверка равенства двух значений 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.
Возвращает napi_ok, если API выполнилось успешно.
Этот API реализует абстрактную операцию ToBoolean, как определено в разделе 7.1.2 спецификации языка ECMAScript. Этот API может быть повторно введён, если для переданного объекта определены геттеры.
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.
Возвращает napi_ok, если API выполнилось успешно.
Этот API реализует абстрактную операцию ToNumber, как определено в разделе 7.1.3 спецификации языка ECMAScript. Этот API может быть повторно введён, если для переданного объекта определены геттеры.
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.
Возвращает napi_ok, если API выполнилось успешно.
Этот API реализует абстрактную операцию ToObject, как определено в разделе 7.1.13 спецификации языка ECMAScript. Этот API может быть повторно введён, если для переданного объекта определены геттеры.
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.
Возвращает napi_ok, если API выполнилось успешно.
Этот API реализует абстрактную операцию ToString, как определено в разделе 7.1.13 спецификации языка ECMAScript. Этот API может быть повторно введён, если для переданного объекта определены геттеры.
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. Однако он поддерживает обнаружение внешнего значения. Если у 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имеет значение true.
Возвращает 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 проверяет, является ли переданный объект буфером массива.
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 проверяет, является ли переданный объект буфером.
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 проверяет, является ли переданный объект объектом 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 проверяет, является ли переданный объект типизированным массивом.
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 проверяет, является ли переданный объект объектом 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 представляет вызов алгоритма Strict Equality, как определено в разделе 7.2.14 спецификации языка ECMAScript.
Работа с JavaScript-свойствами
N-API предоставляет набор API для получения и установки свойств объектов JavaScript. Некоторые из этих типов документированы в разделе 7 Спецификации языка ECMAScript.
Свойства в JavaScript представлены в виде пары ключ-значение. В N-API все ключи свойств могут быть представлены в одном из следующих форматов:
- Именованные: простая строка UTF8
- Индексированные по целочисленному значению: значение индекса, представленное
uint32_t - Значение JavaScript: в N-API они представлены как
napi_value. Это может бытьnapi_value, представляющее строку, число или символ.
Значения N-API представлены типом napi_value. Любой вызов N-API, требующий значение JavaScript, принимает napi_value. Однако ответственность за проверку того, что napi_value имеет ожидаемый тип JavaScript, лежит на вызывающей стороне.
Документированные в этом разделе API предоставляют простой интерфейс для получения и установки свойств произвольных объектов JavaScript, представленных napi_value.
Например, рассмотрим следующий фрагмент JavaScript-кода:
const obj = {};
obj.myProp = 123;
Эквивалент можно реализовать с использованием значений N-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';
Эквивалент можно реализовать с использованием значений N-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];
Приблизительный эквивалент в N-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 }
});
Эквивалент в N-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, 0, 0, 0, fooValue, napi_default, 0 },
{ "bar", NULL, 0, 0, 0, barValue, napi_default, 0 }
}
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,
} 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_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-кода (или если чтение свойства выполняется с помощью вызова N-API). -
setter: Функция, вызываемая при записи в свойство. Если это значение передано, установитеvalueиmethodвNULL(поскольку эти члены не будут использоваться). Данная функция вызывается неявно средой выполнения при записи в свойство из JavaScript-кода (или если запись в свойство выполняется с помощью вызова N-API). -
method: Установите это значение, чтобы сделать свойство объекта-описателяvalueфункцией JavaScript, представленнойmethod. Если это значение передано, установитеvalue,getterиsetterвNULL(поскольку эти члены не будут использоваться). -
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: Среда, в которой вызывается вызов N-API. -
[in] object: Объект, из которого необходимо извлечь свойства. -
[out] result:napi_value, представляющий массив значений JavaScript, которые представляют имена свойств объекта. API можно использовать для итерации поresult, используяnapi_get_array_lengthиnapi_get_element.
Возвращает 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: Среда, в которой вызывается вызов N-API. -
[in] object: Объект, для которого устанавливается свойство. -
[in] key: Имя свойства, которое нужно установить. -
[in] value: Значение свойства.
Возвращает napi_ok, если API успешно выполнено.
Это API устанавливает свойство для переданного объекта.
napi_get_property
napi_status napi_get_property(napi_env env,
napi_value object,
napi_value key,
napi_value* result);
-
[in] env: Среда, в которой вызывается вызов N-API. -
[in] object: Объект, из которого нужно извлечь свойство. -
[in] key: Имя свойства, которое нужно извлечь. -
[out] result: Значение свойства.
Возвращает napi_ok, если API успешно выполнено.
Это API извлекает запрошенное свойство из переданного объекта.
napi_has_property
napi_status napi_has_property(napi_env env,
napi_value object,
napi_value key,
bool* result);
-
[in] env: Среда, в которой вызывается вызов N-API. -
[in] object: Объект, для проверки. -
[in] key: Имя свойства, существование которого нужно проверить. -
[out] result: Существует ли свойство в объекте или нет.
Возвращает napi_ok, если API успешно выполнено.
Это API проверяет, есть ли у переданного объекта свойство с указанным именем.
napi_delete_property
napi_status napi_delete_property(napi_env env,
napi_value object,
napi_value key,
bool* result);
-
[in] env: Среда, в которой вызывается вызов N-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: Среда, в которой вызывается вызов N-API. -
[in] object: Объект, для проверки. -
[in] key: Имя собственного свойства, существование которого нужно проверить. -
[out] result: Существует ли собственное свойство в объекте или нет.
Возвращает napi_ok, если API успешно выполнено.
Это API проверяет, есть ли у переданного объекта указанное собственное свойство. key должно быть строкой или символом, иначе будет выброшено исключение. N-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: Среда, в которой вызывается вызов N-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: Среда, в которой вызывается вызов N-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: Окружение, в котором вызывается вызов N-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: Окружение, в котором вызывается вызов N-API. -
[in] object: Объект, для которого нужно установить свойства. -
[in] index: Индекс свойства для установки. -
[in] value: Значение свойства.
Возвращает napi_ok, если API успешно выполнено.
Этот API устанавливает элемент в переданном объекте.
napi_get_element
napi_status napi_get_element(napi_env env,
napi_value object,
uint32_t index,
napi_value* result);
-
[in] env: Окружение, в котором вызывается вызов N-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: Окружение, в котором вызывается вызов N-API. -
[in] object: Объект для запроса. -
[in] index: Индекс свойства, существование которого нужно проверить. -
[out] result: Существует ли свойство в объекте или нет.
Возвращает napi_ok, если API успешно выполнено.
Этот API возвращает информацию о наличии элемента в объекте по указанному индексу.
napi_delete_element
napi_status napi_delete_element(napi_env env,
napi_value object,
uint32_t index,
bool* result);
-
[in] env: Окружение, в котором вызывается вызов N-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: Окружение, в котором вызывается вызов N-API. -
[in] object: Объект, из которого нужно получить свойства. -
[in] property_count: Количество элементов в массивеproperties. -
[in] properties: Массив описателей свойств.
Возвращает napi_ok, если API успешно выполнено.
Этот метод позволяет эффективно определять несколько свойств в данном объекте. Свойства определяются с помощью описателей свойств (см. napi_property_descriptor). Используя массив таких описателей свойств, этот API будет устанавливать свойства в объекте по одному, как определено в DefineOwnProperty (описано в Разделе 9.1.6 спецификации ECMA262).
Работа с функциями JavaScript
N-API предоставляет набор API, которые позволяют коду JavaScript вызывать нативный код. API N-API, поддерживающие обращение к нативному коду, принимают функции обратного вызова, представленные типом napi_callback. Когда JavaScript VM вызывает нативный код, вызывается функция napi_callback. API, документированные в этом разделе, позволяют функции обратного вызова выполнять следующие действия:
- Получать информацию о контексте, в котором был вызван обратный вызов.
- Получать аргументы, переданные в обратный вызов.
- Возвращать значение
napi_valueиз обратного вызова.
Кроме того, N-API предоставляет набор функций для вызова функций JavaScript из нативного кода. Можно вызывать функцию как обычный вызов JavaScript-функции или как конструктор.
napi_call_function
napi_status napi_call_function(napi_env env,
napi_value recv,
napi_value func,
int argc,
const napi_value* argv,
napi_value* result)
-
[in] env: Окружение, в котором вызывается API. -
[in] recv: Объектthis, переданный вызываемой функции. -
[in] func:napi_value, представляющая функцию JavaScript, которую нужно вызвать. -
[in] argc: Количество элементов в массивеargv. -
[in] argv: Массивnapi_values, представляющих значения JavaScript, переданные в качестве аргументов функции. -
[out] result:napi_value, представляющее возвращённый JavaScript-объект.
Возвращает napi_ok, если API успешно выполнено.
Этот метод позволяет вызвать объект JavaScript-функции из нативного дополнения. Это основной механизм вызова из нативного кода дополнения в JavaScript. Для специального случая вызова в JavaScript после асинхронной операции см. napi_make_callback.
Пример использования может выглядеть следующим образом. Рассмотрим следующий фрагмент JavaScript:
function AddTwo(num) {
return num + 2;
}
Затем, указанную функцию можно вызвать из нативного дополнения с помощью следующего кода:
// 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,
napi_callback cb,
void* data,
napi_value* result);
-
[in] env: Окружение, в котором вызывается API. -
[in] utf8Name: Имя функции, закодированное в UTF8. Оно видно в JavaScript как свойствоnameнового объекта функции. -
[in] cb: Нативная функция, которая должна быть вызвана при вызове этого объекта функции. -
[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, nullptr, &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, не обязательно является именем, переданным в NAPI_MODULE в предыдущем фрагменте, а именем целевого элемента в binding.gyp, отвечающего за создание файла .node.
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: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);
Следующее можно приблизительно реализовать в N-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 успешно выполнился.
Обёртка объекта
N-API предоставляет способ «обёртки» C++-классов и экземпляров, чтобы конструктор и методы класса могли вызываться из JavaScript.
- API
napi_define_classопределяет JavaScript-класс с конструктором, статическими свойствами и методами, а также свойствами и методами экземпляров, соответствующими C++-классу. - Когда JavaScript-код вызывает конструктор, обратный вызов конструктора использует
napi_wrap, чтобы обернуть новый C++-экземпляр в JavaScript-объект и вернуть объект-обёртку. - Когда JavaScript-код вызывает метод или свойство доступа к классу, вызывается соответствующая
napi_callbackC++-функция. Для обратного вызова экземпляра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_define_class
-
[in] env: Окружение, в котором вызывается API. -
[in] utf8name: Имя JavaScript-функции-конструктора; оно не обязательно должно совпадать с именем C++-класса, хотя для ясности рекомендуется. -
[in] length: Длина utf8name в байтах илиNAPI_AUTO_LENGTH, если она завершена нулём. -
[in] constructor: Функция обратного вызова, обрабатывающая создание экземпляров класса. (Это должен быть статический метод класса, а не фактическая C++-функция-конструктор). -
[in] data: Дополнительные данные, передаваемые в функцию обратного вызова как свойствоdataинформации о вызове. -
[in] property_count: Количество элементов в массивеpropertiesаргумента. -
[in] properties: Массив описателей свойств, описывающих статические и экземплярные данные, аксессоры и методы класса. См.napi_property_descriptor. -
[out] result:napi_value, представляющий функцию-конструктор класса.
Возвращает napi_ok, если API успешно выполнился.
Определяет JavaScript-класс, соответствующий C++-классу, включая:
- JavaScript-функцию-конструктор, имеющую имя класса и вызывающую предоставленный C++-обратный вызов конструктора.
- Свойства в функции-конструкторе, соответствующие статическим данным, аксессорам и методам C++-класса (определены описателями свойств с атрибутом
napi_static). - Свойства в объекте
prototypeфункции-конструктора, соответствующие нестатическим данным, аксессорам и методам C++-класса (определены описателями свойств без атрибутаnapi_static).
C++-обратный вызов конструктора должен быть статическим методом класса, который вызывает фактический конструктор класса, затем оборачивает новый C++-экземпляр в JavaScript-объект и возвращает объект-обёртку. Подробнее см. napi_wrap().
Функция-конструктор JavaScript, возвращаемая napi_define_class, часто сохраняется и используется позже для создания новых экземпляров класса из кода на C++, а также для проверки того, являются ли предоставленные значения экземплярами класса. В этом случае, чтобы предотвратить сборку мусора функции, создайте постоянную ссылку на неё с помощью napi_create_reference и убедитесь, что счётчик ссылок остаётся ≥ 1.
napi_wrap
-
[in] env: Окружение, в котором вызывается API. -
[in] js_object: JavaScript-объект, который будет обёрткой для нативного объекта. Этот объект обязательно должен быть создан изprototypeконструктора, который был создан с помощьюnapi_define_class(). -
[in] native_object: Нативный экземпляр, который будет обернут в JavaScript-объект. -
[in] finalize_cb: Необязательный нативный обратный вызов, который можно использовать для освобождения нативного экземпляра, когда JavaScript-объект готов к сбору мусора. -
[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 для правильного управления ссылкой.
Примечание: Этот API может изменить цепочку прототипов объекта-обёртки. После этого дополнительные манипуляции с цепочкой прототипов обёртки могут привести к тому, что napi_unwrap() не сработает.
Вызов napi_wrap() во второй раз для объекта вернёт ошибку. Чтобы связать другой нативный экземпляр с объектом, сначала используйте napi_remove_wrap().
napi_unwrap
-
[in] env: Окружение, в котором вызывается API. -
[in] js_object: Объект, связанный с нативным экземпляром. -
[out] result: Указатель на обернутый нативный экземпляр.
Возвращает napi_ok, если API успешно выполнился.
Получает нативный экземпляр, который был ранее обернут в JavaScript-объект с помощью napi_wrap().
Когда JavaScript-код вызывает метод или аксессор свойства для класса, вызывается соответствующая napi_callback. Если обратный вызов предназначен для метода или аксессора экземпляра, то аргументом this обратного вызова является объект-обёртка; обернутый C++-экземпляр, являющийся целевым для вызова, можно получить, вызвав napi_unwrap() для объекта-обёртки.
napi_remove_wrap
-
[in] env: Окружение, в котором вызывается API. -
[in] js_object: Объект, связанный с нативным экземпляром. -
[out] result: Указатель на обернутый нативный экземпляр.
Возвращает napi_ok, если API успешно выполнился.
Получает нативный экземпляр, который был ранее обернут в JavaScript-объект js_object с помощью napi_wrap() и удаляет обёртку, тем самым восстанавливая цепочку прототипов JavaScript-объекта. Если с обёрткой был связан обратный вызов finalize, он больше не будет вызываться при сборе мусора JavaScript-объекта.
Простые асинхронные операции
Модулям дополнений часто требуется использовать асинхронные помощники из libuv в рамках их реализации. Это позволяет им планировать выполнение работы асинхронно, чтобы их методы могли возвращаться до завершения работы. Это важно, чтобы они не блокировали общее выполнение приложения Node.js.
N-API предоставляет ABI-стабильный интерфейс для этих вспомогательных функций, охватывающий наиболее распространённые случаи асинхронного использования.
N-API определяет структуру napi_work, которая используется для управления асинхронными рабочими процессами. Экземпляры создаются/удаляются с помощью napi_create_async_work и napi_delete_async_work.
Обратные вызовы execute и complete — это функции, которые будут вызваны, когда исполнитель готов к выполнению и по завершении задачи соответственно. Эти функции реализуют следующие интерфейсы:
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: Необязательный объект, связанный с асинхронной работой, который будет передан возможным асинхронным хукамinit. -
[in] async_resource_name: Идентификатор типа ресурса, предоставляемого для диагностической информации, экспонируемой APIasync_hooks. -
[in] execute: Нативная функция, которая должна вызываться для выполнения логики асинхронно. Данная функция вызывается из потока пула рабочих процессов и может выполняться параллельно с основным потоком событий. -
[in] complete: Нативная функция, которая будет вызвана по завершении или отмене асинхронной логики. Данная функция вызывается из основного потока событий. -
[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 запрашивает планирование ранее выделенной работы для выполнения.
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, чтобы убедиться, что асинхронная операция должным образом отслеживается runtime.
napi_async_init
napi_status napi_async_init(napi_env env,
napi_value async_resource,
napi_value async_resource_name,
napi_async_context* result)
-
[in] env: Окружение, в котором вызывается API. -
[in] async_resource: Необязательный объект, связанный с асинхронной работой, который будет передан возможнымasync_hooksinitхукам. -
[in] async_resource_name: Идентификатор типа ресурса, предоставляемого для диагностической информации, экспонируемой APIasync_hooks. -
[out] result: Инициализированный контекст асинхронной операции.
Возвращает napi_ok, если API успешно выполнился.
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_status napi_make_callback(napi_env env,
napi_async_context async_context,
napi_value recv,
napi_value func,
int argc,
const napi_value* argv,
napi_value* result)
-
[in] env: Окружение, в котором вызывается API. -
[in] async_context: Контекст асинхронной операции, которая вызывает обратный вызов. Обычно это значение, полученное ранее изnapi_async_init. Однако, также допускаетсяNULL, что указывает на использование текущего контекста асинхронной операции (если таковой имеется) для обратного вызова. -
[in] recv: Объект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.
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: Необязательный объект, связанный с асинхронной работой, который будет передан возможным асинхронным хукамinit. -
[in] context: Контекст асинхронной операции, вызывающей обратный вызов. Это должно быть значение, полученное ранее изnapi_async_init. -
[out] result: Созданный контекст.
Существуют случаи (например, разрешение промисов), когда необходимо иметь эквивалент контекста, связанного с обратным вызовом, когда выполняются определённые вызовы N-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.
Возвращает napi_ok, если API успешно выполнился.
Эта функция заполняет структуру version главными, второстепенными и исправленными версиями 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: Наивысшая поддерживаемая версия N-API.
Возвращает napi_ok, если API успешно выполнился.
Этот API возвращает самую высокую версию N-API, поддерживаемую средой выполнения Node.js. N-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, указывающий на собственную память, выделенную нативным модулем). Регистрация внешней выделенной памяти будет чаще вызывать глобальные сборки мусора, чем в противном случае.
Обещания
N-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 promise,
bool* is_promise);
-
[in] env: Среда, в которой вызывается API. -
[in] promise: Обещание для проверки -
[out] is_promise: Флаг, указывающий, является лиpromiseобъектом нативного обещания — то есть объектом обещания, созданным базовым движком.
Выполнение скрипта
N-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: Значение, полученное в результате выполнения скрипта.
Цикл событий libuv
N-API предоставляет функцию для получения текущего цикла событий, связанного с определенным napi_env.
napi_get_uv_event_loop
NAPI_EXTERN napi_status napi_get_uv_event_loop(napi_env env,
uv_loop_t** loop);
-
[in] env: Среда, в которой вызывается API. -
[out] loop: Текущий экземпляр цикла libuv.
Асинхронные потокобезопасные вызовы функций
Функции JavaScript обычно могут вызываться только из основного потока нативного дополнения. Если дополнение создает дополнительные потоки, то функции N-API, требующие napi_env, napi_value или napi_ref, не должны вызываться из этих потоков.
Когда дополнение имеет дополнительные потоки, и функции JavaScript необходимо вызывать на основе обработки, завершённой этими потоками, эти потоки должны взаимодействовать с основным потоком дополнения, чтобы главный поток мог вызывать функцию JavaScript от их имени. Потокобезопасные API предоставляют простой способ сделать это.
Эти API предоставляют тип napi_threadsafe_function, а также API для создания, уничтожения и вызова объектов этого типа. napi_create_threadsafe_function() создает постоянную ссылку на napi_value, который содержит функцию JavaScript, которую можно вызывать из нескольких потоков. Вызовы происходят асинхронно. Это означает, что значения, с которыми должна быть вызвана обратная функция JavaScript, будут помещены в очередь, и для каждого значения в очереди в конечном итоге будет сделан вызов функции JavaScript.
При создании napi_threadsafe_function может быть предоставлена обратная функция napi_finalize. Эта обратная функция будет вызвана в главном потоке, когда потокобезопасная функция будет уничтожена. Она получает контекст и данные завершения, предоставленные во время создания, и предоставляет возможность очистить данные после потоков, например, вызвав uv_thread_join(). Важно, чтобы помимо основного потока цикла не осталось потоков, использующих потокобезопасную функцию после завершения обратной функции завершения.
context, предоставленное во время вызова napi_create_threadsafe_function(), может быть получено из любого потока с помощью вызова napi_get_threadsafe_function_context().
napi_call_threadsafe_function() затем может использоваться для инициирования вызова в JavaScript. napi_call_threadsafe_function() принимает параметр, который управляет поведением API, блокирующим ли оно. Если он установлен в napi_tsfn_nonblocking, API ведет себя неблокирующим образом, возвращая napi_queue_full, если очередь была полной, предотвращая добавление данных в очередь. Если он установлен в napi_tsfn_blocking, API блокируется до тех пор, пока не освободится место в очереди. napi_call_threadsafe_function() никогда не блокируется, если потокобезопасная функция была создана с максимальным размером очереди 0.
Фактический вызов в 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() не обязательно, потому что N-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().
После того, как количество потоков, использующих 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_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-функция, вызываемая из другого потока. -
[in] async_resource: Дополнительный объект, связанный с асинхронной работой, который будет передан возможнымasync_hooksinitобработчикам. -
[in] async_resource_name: JavaScript-строка, предоставляющая идентификатор типа ресурса для диагностической информации, представленной APIasync_hooks. -
[in] max_queue_size: Максимальный размер очереди. 0 — без ограничения. -
[in] initial_thread_count: Начальное число потоков, включая основной поток, которые будут использовать эту функцию. -
[in] thread_finalize_data: Дополнительные данные, передаваемые вthread_finalize_cb. -
[in] thread_finalize_cb: Дополнительная функция, вызываемая при уничтоженииnapi_threadsafe_function. -
[in] context: Дополнительные данные для добавления к результирующемуnapi_threadsafe_function. -
[in] call_js_cb: Необязательный обратный вызов, вызывающий JavaScript-функцию в ответ на вызов в другом потоке. Этот обратный вызов будет вызван в основном потоке. Если не указан, JavaScript-функция будет вызвана без параметров и со значениемundefinedв качестве своего значенияthis. -
[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] context: Место для хранения контекста.
Этот 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_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, он также идемпотентен.
Этот 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 может быть вызван только из главного потока.
© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v8.x/docs/api/n-api.html