如何在Native侧调用ArkTS侧异步方法，并获取异步计算结果到Native侧
========================================

该场景可以通过在Native侧获取ArkTS侧的Promise对象来实现。具体步骤如下：

*   ArkTS侧实现：
    1.  调用Native接口时，传入callback回调；在回调中构造Promise对象。
    2.  在Promise构造函数的参数回调中，实现异步操作，并根据操作结果调用resolve或reject接口，以进行Promise对象的状态迁移。
*   Native侧实现：
    1.  定义Promise对象的then属性回调方法，用于处理ArkTS中的异步计算结果。
    2.  定义Promise对象的catch方法，用于处理ArkTS异步计算中的异常。
    3.  在Native接口实现中，使用napi\_call\_function接口执行ArkTS侧传入的callback回调，获取Promise对象。
    4.  通过napi\_get\_named\_property接口获取 Promise 对象的then和catch属性。
    5.  通过napi\_create\_function接口将上述定义的then和catch属性的 C++ 回调方法转换为 ArkTS 函数对象。
    6.  通过napi\_call\_function接口执行then和catch属性对应的 ArkTS 函数对象，处理异步计算结果和异常信息。类似于在 ArkTS 侧调用“promise.then(() => {})和promise.catch(() => {})”。

具体可参考以下示例代码：

（一）ArkTS侧实现

_// ..._
import testNapi from 'libentry.so';

@Entry
@Component
struct Index {
  build() {
    Row() {
      Column() {
        Text('testPromise')
         _ // ..._
          .onClick(() => {
            hilog.info(0x0000, 'testTag-ArkTS', 'Before calling the native interface.');
          _  // Call the Native interface and return the call information_
            testNapi.testPromise(() => {
             _ // Callback is used to create ArkTS side Promise objects_
              return new Promise((resolve: Function, reject: Function) => {
              _  // Simulate ArkTS side asynchronous method through setTimeout interface_
                _// Scenario: After 2 seconds, trigger the setTimeout timer callback to generate a random number randomNumber. By judging the size of the random number, it is used to trigger different states of the promise object, and then perform different callback processing_
                setTimeout(()=>{
                  const randomNumber: number = 100 \* Math.random();
                  if (randomNumber > 50) {
                   _ // If randomNumber is greater than 50, call the resolve method to transition the state of the Promise object to the fulfilled state, and pass the random number to the Native side as a callback parameter for the then method_
                    resolve(randomNumber);
                  } else {
                  _  // If randomNumber is less than/equal to 50, call the reject method to transfer the state of the Promise object to the rejected state, and pass the exception information to the Native side as the callback parameter of the catch method_
                    reject('The random number is less than 50, so the promise object is rejected.')
                  }
                }, 2000);
              })
            }
            )
            hilog.info(0x0000, 'testTag-ArkTS', 'After the native interface is called.');
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

（二）Native侧实现

#include "napi/native\_api.h" 
#include "hilog/log.h" 
 
_// Define callback methods for the then property of Promise objects_ 
_// The callback method of the then attribute can have no return value_ 
_// In the following text, it is necessary to create an ArkTS function object through napi\_make\_function, so set the return value to napi\_value and return nullptr at the end of the function_
napi\_value ThenCallBack(napi\_env env, napi\_callback\_info info) { 
    size\_t argc = 1; 
    napi\_value args\[1\] = {nullptr}; 
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr); 
    int32\_t asyncResult = 0; _// ArkTS side asynchronous method calculation results_ 
    napi\_get\_value\_int32(env, args\[0\], &asyncResult); 
    OH\_LOG\_Print(LOG\_APP, LOG\_INFO, 0xFF00, "testTag-Native", "ArkTS Async Method Calculation Success, Result: %{public}d", 
                 asyncResult); 
    return nullptr; 
} 
_// Define callback methods for catch properties of Promise objects_ 
_// The callback method of the catch property can have no return value_ 
_// In the following text, it is necessary to create an ArkTS function object through napi\_make\_function, so set the return value to napi\_value and return nullptr at the end of the function_ 
napi\_value CatchCallBack(napi\_env env, napi\_callback\_info info) { 
    size\_t argc = 1; 
    napi\_value args\[1\] = {nullptr}; 
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr); 
    size\_t strLen = 0; 
    napi\_get\_value\_string\_utf8(env, args\[0\], nullptr, 0, &strLen);           _// Get string length to strLen_ 
    char \*strBuffer = new char\[strLen + 1\];                                  _// Allocate a char array of appropriate size_ 
    napi\_get\_value\_string\_utf8(env, args\[0\], strBuffer, strLen + 1, &strLen); _// Get a string representing the information about the abnormal_ _calculation of the ArkTS side asynchronous method_
    OH\_LOG\_Print(LOG\_APP, LOG\_INFO, 0xFF00, "testTag-Native", 
                 "ArkTS Async Method Calculation Exception: %{public}s", strBuffer); 
    return nullptr; 
} 
static napi\_value TestPromise(napi\_env env, napi\_callback\_info info) { 
    size\_t argc = 1; 
    napi\_value args\[1\] = {nullptr}; 
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr); _// Analyze the callback passed by ArkTS side_ 
 
    napi\_value arktsPromise = nullptr; 
   _ // Execute callback through napi\_call\_function to return the promise object created by ArkTS side_
    napi\_call\_function(env, nullptr, args\[0\], 0, nullptr, &arktsPromise); 
 
   _ // Get the then property of the promise object, whose callback method is used to handle the asynchronous calculation results on the ArkTS side_
    napi\_value thenProperty = nullptr; 
    napi\_get\_named\_property(env, arktsPromise, "then", &thenProperty); 
  _  // Convert the then property callback method defined in the C++language into an ArkTS function object, which is a napi\_value type value_
    napi\_value thenCallback = nullptr; 
    napi\_create\_function(env, "thenCallback", NAPI\_AUTO\_LENGTH, ThenCallBack, nullptr, &thenCallback); 
 
   _// Get the catch property of the promise object, whose callback method is used to handle information about ArkTS side asynchronous computation exceptions_ 
    napi\_value catchProperty = nullptr; 
    napi\_get\_named\_property(env, arktsPromise, "catch", &catchProperty); 
  _  // Convert the catch property callback method defined in the C++language into an ArkTS function object, i.e. a napi\_value type value_
    napi\_value catchCallback = nullptr; 
    napi\_create\_function(env, "catchCallback", NAPI\_AUTO\_LENGTH, CatchCallBack, nullptr, &catchCallback); 
     
   _ // Execute the callback of the then attribute through napi\_call\_function, similar to calling promise. then()=>{} on the ArkTS side_
    napi\_call\_function(env, arktsPromise, thenProperty, 1, &thenCallback, nullptr); 
 _   // Execute a callback for the catch property through napi\_call\_function, similar to calling promise. catch (()=>{}) on the ArkTS side_
    napi\_call\_function(env, arktsPromise, catchProperty, 1, &catchCallback, nullptr); 
    return nullptr; 
}

运行结果

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/7c/v3/hIFuR6U0SPe3AlepSSI9EA/zh-cn_image_0000002624635810.png?HW-CC-KV=V1&HW-CC-Date=20260709T133837Z&HW-CC-Expire=86400&HW-CC-Sign=41B34C18AA1DD6A4B48959C40B2947B9FF7F86BA39386121BA17082C7233E435 "点击放大")

*   结果（1）：表示ArkTS侧调用Native接口后，Native侧运行未阻塞，直接返回。
*   结果（2）：表示ArkTS侧调用Native接口后，等待2秒（异步计算）。如果异步操作中生成的随机数小于或等于50，通过Promise对象的reject接口传入异常信息到Native侧，并通过catch回调进行处理。
*   结果（3）：表示ArkTS侧调用Native接口后，等待2秒（异步计算）。如果异步操作中生成的随机数大于50，则通过Promise对象的resolve接口将该随机数传入Native侧，并通过then回调进行处理和显示。