The simple asynchronous work APIs above may not be appropriate for every scenario. When using any other asynchronous mechanism, the following APIs are necessary to ensure an asynchronous operation is properly tracked by the runtime.
napi_async_init
#napi_status napi_async_init(napi_env env,
napi_value async_resource,
napi_value async_resource_name,
napi_async_context* result)
[in] env
: The environment that the API is invoked under.[in] async_resource
: Object associated with the async work that will be passed to possible async_hooks
init
hooks and can be accessed by async_hooks.executionAsyncResource()
.[in] async_resource_name
: Identifier for the kind of resource that is being provided for diagnostic information exposed by the async_hooks
API.[out] result
: The initialized async context.Returns napi_ok
if the API succeeded.
The async_resource
object needs to be kept alive until napi_async_destroy
to keep async_hooks
related API acts correctly. In order to retain ABI compatibility with previous versions, napi_async_context
s are not maintaining the strong reference to the async_resource
objects to avoid introducing causing memory leaks. However, if the async_resource
is garbage collected by JavaScript engine before the napi_async_context
was destroyed by napi_async_destroy
, calling napi_async_context
related APIs like napi_open_callback_scope
and napi_make_callback
can cause problems like loss of async context when using the AsyncLocalStorage
API.
In order to retain ABI compatibility with previous versions, passing NULL
for async_resource
does not result in an error. However, this is not recommended as this will result poor results with async_hooks
init
hooks and async_hooks.executionAsyncResource()
as the resource is now required by the underlying async_hooks
implementation in order to provide the linkage between async callbacks.
napi_async_destroy
#napi_status napi_async_destroy(napi_env env,
napi_async_context async_context);
[in] env
: The environment that the API is invoked under.[in] async_context
: The async context to be destroyed.Returns napi_ok
if the API succeeded.
This API can be called even if there is a pending JavaScript exception.
napi_make_callback
#NAPI_EXTERN napi_status napi_make_callback(napi_env env,
napi_async_context async_context,
napi_value recv,
napi_value func,
size_t argc,
const napi_value* argv,
napi_value* result);
[in] env
: The environment that the API is invoked under.[in] async_context
: Context for the async operation that is invoking the callback. This should normally be a value previously obtained from napi_async_init
. In order to retain ABI compatibility with previous versions, passing NULL
for async_context
does not result in an error. However, this results in incorrect operation of async hooks. Potential issues include loss of async context when using the AsyncLocalStorage
API.[in] recv
: The this
value passed to the called function.[in] func
: napi_value
representing the JavaScript function to be invoked.[in] argc
: The count of elements in the argv
array.[in] argv
: Array of JavaScript values as napi_value
representing the arguments to the function. If argc
is zero this parameter may be omitted by passing in NULL
.[out] result
: napi_value
representing the JavaScript object returned.Returns napi_ok
if the API succeeded.
This method allows a JavaScript function object to be called from a native add-on. This API is similar to napi_call_function
. However, it is used to call from native code back into JavaScript after returning from an async operation (when there is no other script on the stack). It is a fairly simple wrapper around node::MakeCallback
.
Note it is not necessary to use napi_make_callback
from within a napi_async_complete_callback
; in that situation the callback's async context has already been set up, so a direct call to napi_call_function
is sufficient and appropriate. Use of the napi_make_callback
function may be required when implementing custom async behavior that does not use napi_create_async_work
.
Any process.nextTick
s or Promises scheduled on the microtask queue by JavaScript during the callback are ran before returning back to C/C++.
napi_open_callback_scope
#NAPI_EXTERN napi_status napi_open_callback_scope(napi_env env,
napi_value resource_object,
napi_async_context context,
napi_callback_scope* result)
[in] env
: The environment that the API is invoked under.[in] resource_object
: An object associated with the async work that will be passed to possible async_hooks
init
hooks. This parameter has been deprecated and is ignored at runtime. Use the async_resource
parameter in napi_async_init
instead.[in] context
: Context for the async operation that is invoking the callback. This should be a value previously obtained from napi_async_init
.[out] result
: The newly created scope.There are cases (for example, resolving promises) where it is necessary to have the equivalent of the scope associated with a callback in place when making certain Node-API calls. If there is no other script on the stack the napi_open_callback_scope
and napi_close_callback_scope
functions can be used to open/close the required scope.
napi_close_callback_scope
#NAPI_EXTERN napi_status napi_close_callback_scope(napi_env env,
napi_callback_scope scope)
[in] env
: The environment that the API is invoked under.[in] scope
: The scope to be closed.This API can be called even if there is a pending JavaScript exception.