harmony 鸿蒙Customizing Asynchronous Operations Using Node-API

  • 2025-06-12
  • 浏览 (2)

Customizing Asynchronous Operations Using Node-API

Introduction

Node-API provides APIs for customizing asynchronous (async for short) operations to handle time-consuming tasks that may block event loops while maintaining quick response and high performance of ArkTS applications.

Basic Concepts

Async operations are used to complete I/O-intensive or compute-intensive tasks, which usually need to be executed without blocking the main thread. Before you get started, understand the following concepts:

  • Async model: Node-API provides APIs that implement async operations using a promise or a callback. Promise is a programming model based on future values. It allows results of async operations to be encapsulated in objects and called in a chain. Callback is a traditional async programming mode. It uses callback functions to process async operation results.
  • Temporary result: When a native method (Node-API) is called, it immediately returns a temporary result to the ArkTS caller. The temporary result is usually a flag indicating an async operation being performed or a handle for subsequent processing of an async operation result.
  • Callback/Promise: When an async operation is complete, the result is returned to the ArkTS caller through a callback function or a promise object. This allows the processing of the subsequent logic after the async operation is complete.

Available APIs

The following table lists the APIs provided by the Node-API module for customizing async operations. You can use these APIs to implement ArkTS callbacks and manage the resource lifecycle in C/C++. These APIs help implement complex async operations and effective interaction with ArkTS.
|API|Description| |——–|——–| |napi_async_init, napi_async_destroy|Creates/Destroys an async context.
You can use these APIs to handle time-consuming tasks, such as file I/O operations and network requests, without blocking the main thread. You can use napi_async_init to create an async context for executing the task, and use napi_async_destroy after the task is complete to destroy and release related resources.| |napi_make_callback|Executes an ArkTS callback function in an async context and returns the operation result to ArkTS.| |napi_open_callback_scope, napi_close_callback_scope|Opens/Closes a callback scope. You can use these APIs to execute ArkTS code and manage its context during the async operation.|

Example

If you are just starting out with Node-API, see Node-API Development Process. The following demonstrates only the C++ and ArkTS code involved in the APIs for customizing async operations.

napi_async_init and napi_async_destroy

Use napi_async_init to create an async context, and use napi_async_destroy to destroy an async context. Note that these APIs do not support capabilities related to async_hook.

napi_make_callback

To call and execute an ArkTS callback after an async operation is complete, use napi_make_callback.

napi_open_callback_scope and napi_close_callback_scope

To make the ArkTS context still available during an async operation, use napi_open_callback_scope to create a scope for the callback. You can use napi_close_callback_scope to close the scope after the async operation is complete.

CPP code:

#include "napi/native_api.h"

static napi_value AsynchronousWork(napi_env env, napi_callback_info info)
{
    // Initialize an array to hold four parameters.
    size_t argc = 4;
    napi_value args[4] = {nullptr};
    // Obtain parameters from the callback information.
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    // Extract resources, receiver objects, and functions from the parameters.
    napi_value resource = args[0];
    napi_value recv = args[1];
    napi_value func = args[2];
    napi_value argv[1] = {nullptr};
    argv[0] = args[3];
    // Obtain the function type.
    napi_valuetype funcType;
    napi_typeof(env, func, &funcType);
    // Create a string named "test".
    napi_value resourceName = nullptr;
    napi_create_string_utf8(env, "test", NAPI_AUTO_LENGTH, &resourceName);
    // Initialize the async context.
    napi_async_context context;
    napi_status status = napi_async_init(env, resource, resourceName, &context);
    if (status != napi_ok) {
        napi_throw_error(env, nullptr, "napi_async_init fail");
        return nullptr;
    }
    // Open a callback scope.
    napi_callback_scope scope = nullptr;
    napi_open_callback_scope(env, resource, context, &scope);
    if (status != napi_ok) {
        napi_throw_error(env, nullptr, "napi_open_callback_scope fail");
        return nullptr;
    }
    // Invoke the callback function defined.
    napi_value result = nullptr;
    if (funcType == napi_function) {
        napi_make_callback(env, context, recv, func, 1, argv, &result);
    } else {
        napi_throw_error(env, nullptr, "Unexpected argument type");
        return nullptr;
    }
    // Close the callback scope.
    napi_close_callback_scope(env, scope);
    if (status != napi_ok) {
        napi_throw_error(env, nullptr, "napi_close_callback_scope fail");
        return nullptr;
    }
    // Destroy the async context.
    napi_async_destroy(env, context);
    return result;
}

API declaration:

// index.d.ts
export const asynchronousWork: (object: Object, obj: Object, fun: Function, num: number) => number|void;

ArkTS code:

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'
import process from '@ohos.process'
try {
  hilog.info(0x0000, 'testTag', 'Test Node-API asynchronousWork: %{public}d', testNapi.asynchronousWork({}, process.ProcessManager, (num: number)=>{return num;}, 123));
} catch (error) {
  hilog.error(0x0000, 'testTag', 'Test Node-API asynchronousWork error: %{public}s', error.message);
}

To print logs in the native CPP, add the following information to the CMakeLists.txt file and add the header file by using #include “hilog/log.h”.

// CMakeLists.txt
add_definitions( "-DLOG_DOMAIN=0xd0d0" )
add_definitions( "-DLOG_TAG=\"testTag\"" )
target_link_libraries(entry PUBLIC libhilog_ndk.z.so )

你可能感兴趣的鸿蒙文章

harmony 鸿蒙Node-API

harmony 鸿蒙Building an NDK Project with CMake

harmony 鸿蒙Building an NDK Project with the DevEco Studio Template

harmony 鸿蒙NDK Project Building Overview

harmony 鸿蒙Building an NDK Project with Prebuilt Libraries

harmony 鸿蒙C/C++ Library Mechanisms

harmony 鸿蒙CPU Features

harmony 鸿蒙Creating an NDK Project

harmony 鸿蒙C/C++ Memory Error Detection

harmony 鸿蒙Debugging in DevEco Studio

0  赞