使用Promise实现一种串行调用方式

​Native C++层调用Arkts层的函数,该函数返回的结果为Promise,通过,如果在C++层获取到Promise对象的返回结果(结果中包含resolve和reject的值)。

HarmonyOS
2024-05-23 21:36:11
浏览
已于2024-5-24 16:37:52修改
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
NingJ

使用的核心API

Promise
napi_get_cb_info
napi_create_reference
napi_delete_reference
napi_call_function
napi_create_function

核心代码解释

Index.ets中ArkTS层定义的返回Promise的函数:

function TestPromise(): Promise<Object> {   
  hilog.info(0x0000, 'testTag', 'enter TestPromise');   
  return new Promise((resolve: Function, reject: Function) => {   
    hilog.info(0x0000, 'testTag', 'resolve:%{public}d', result);   
    if (result == 1) {   
      result = 2;   
      resolve(testClass);   
    } else {   
      result = 1;   
      reject(1000);   
    }   
  });   
}

C++层:

注册ArkTs层的处理函数:

static napi_value RegisterFun(napi_env env, napi_callback_info info)   
{   
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "enter RegisterFun: %{public}ld", pthread_self());   
       
    size_t argc = 1;   
    g_env = env;   
   
    napi_value ets_fun;   
    napi_get_cb_info(env, info, &argc, &ets_fun, nullptr, nullptr);   
    napi_create_reference(env, ets_fun, 1, &g_funRef);   
   
    return nullptr;   
}

C++执行回调函数的处理:

static napi_value StartHandle(napi_env env, napi_callback_info info)   
{   
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "enter StartHandle: %{public}ld", pthread_self());   
       
    napi_value ets_fun;   
    napi_value result = nullptr;   
    napi_value promiseObj = nullptr;   
       
    if (g_funRef == nullptr) {   
        OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, LOG_TAG, "StartHandle g_funRef == nullptr");   
        return nullptr;   
    }   
   
    napi_get_reference_value(env, g_funRef, &ets_fun);   
    napi_call_function(env, nullptr, ets_fun, 0, nullptr, &promiseObj);   
   
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "start StartHandle");   
   
    napi_value promiseThen = nullptr;   
    napi_get_named_property(env, promiseObj, "then", &promiseThen);   
   
   
    napi_call_function(env, promiseObj, promiseThen, 0, nullptr, &result);   
   
    napi_delete_reference(env, g_funRef);   
    g_funRef = nullptr;   
   
    napi_value resolvedCallback;   
    napi_value rejectedCallback;   
    napi_create_function(env, "resolvedCallback", strlen("resolvedCallback"), ResolvedCallback, nullptr,   
                         &resolvedCallback);   
    napi_create_function(env, "rejectedCallback", strlen("rejectedCallback"), RejectedCallback, nullptr,   
                         &rejectedCallback);   
    napi_value argv[2] = {resolvedCallback, rejectedCallback};   
    napi_call_function(env, promiseObj, promiseThen, 2, argv, nullptr);   
   
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "end StartHandle");   
    return nullptr;   
}

Promise的resolve和reject处理:

static napi_value ResolvedCallback(napi_env env, napi_callback_info info) {   
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "enter ResolvedCallback: %{public}ld", pthread_self());   
    size_t argc = 1;   
    napi_value args[1];   
    if (napi_get_cb_info(env, info, &argc, args, nullptr, nullptr) != napi_ok) {   
        OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, LOG_TAG, "ResolvedCallback napi_get_cb_info is not napi_ok");   
        return nullptr;   
    }   
   
    napi_valuetype type;   
    napi_typeof(env, args[0], &type);   
    if (type != napi_valuetype::napi_object) {   
        OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, LOG_TAG, "ResolvedCallback type(%d) != napi_valuetype::napi_object", type);   
        return nullptr;   
    }   
   
    // 从arg[0]中获取ts侧传递的对象   
    napi_value objectValue;   
    napi_create_object(env, &objectValue);   
    napi_coerce_to_object(env, args[0], &objectValue);   
{   
    napi_value ets_fun;   
    napi_get_reference_value(env, g_callbackRef, &ets_fun);   
    napi_call_function(env, nullptr, ets_fun, 1, &args[0], nullptr);   
}   
    // 获取类中的方法   
    napi_value funHandle;   
    napi_get_named_property(env, objectValue, "GetValue", &funHandle);   
   
    napi_value result;   
    napi_call_function(env, objectValue, funHandle, 0, nullptr, &result);   
   
    int  iResult = 0;   
    napi_get_value_int32(env, result, &iResult);   
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "ResolvedCallback iResult: %{public}d", iResult);   
       
    return result;   
}   
   
static napi_value RejectedCallback(napi_env env, napi_callback_info info) {   
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "enter RejectedCallback: %{public}ld", pthread_self());   
    size_t argc = 1;   
    napi_value args[1];   
    if (napi_get_cb_info(env, info, &argc, args, nullptr, nullptr) != napi_ok) {   
        OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, LOG_TAG, "RejectedCallback napi_get_cb_info is not napi_ok");   
        return nullptr;   
    }   
   
    napi_valuetype type;   
    napi_typeof(env, args[0], &type);   
    if (type != napi_valuetype::napi_number) {   
        OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, LOG_TAG, "RejectedCallback type != napi_valuetype::napi_number");   
        return nullptr;   
    }   
    int iResult = 0;   
    napi_get_value_int32(env, args[0], &iResult);   
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, LOG_TAG, "RejectedCallback iResult: %{public}d", iResult);   
   
    return args[0];   
}

实现效果

点击第一个Hello World后,再次点击start后,执行结果如下:

适配的版本信息

IDE:DevEco Studio 4.1.1.300

SDK:HarmoneyOS 4.0.10.15

分享
微博
QQ
微信
回复
2024-05-24 16:33:36
相关问题
HarmonyOS 求一种类似总线通知的功能
348浏览 • 1回复 待解决
视频进度滑动条的三实现方式
1510浏览 • 1回复 待解决
PolarDB 支持哪些扩容方式
3705浏览 • 1回复 待解决
HarmonyOS 怎么实现任务串行顺序执行
360浏览 • 1回复 待解决
HarmonyOS Promise & taskpool使用问题
280浏览 • 1回复 待解决
js获取canvas对象两方式有啥不同?
7570浏览 • 1回复 待解决