promise实例在C++和JS之间的传递

场景1:js 侧接收 C++ 侧创建的 Promise 实例

基本流程

  1. C++ 侧调用 napi_create_promise 创建新的的延迟对象 deferred 与延迟对象相关联的 JavaScript promise。
  2. promise 实例通过接口返回给 JS 侧使用。
  3. deferrd 延迟对象用全局上下文对象保存,只要 deferrd 对象没被销毁,C++ 侧、就可以在任意方法内、任意时机去控制 JS 侧 Promise 实例的状态(fulfilled/rejected)。

示例代码

JS 侧
Row() {
	Text("getPromise")
		.fontSize(50)
		.fontWeight(FontWeight.Bold)
		.onClick(() => {
			// 接收 c++ 侧 传来的 promise 并使用
			let promise1 = testNapi.getPromise();
			promise1.then((val)=>{
				hilog.info(0x0000, 'testTag', 'Test NAPI getPromise res is %{public}s', JSON.stringify(val));
			})
		})
}
C++ 侧
// 定义 promise 相关数据结构体(全局)
struct promiseInfo {
    napi_async_work worker; // 用来存储操作异步 work 句柄
    napi_deferred deferred; // 存储延迟对象,用于操作 promise
    char *val; // 存储 resolve/reject 函数调用时的参数
};

// 全局实例化 结构体数据
struct promiseInfo data = { nullptr, nullptr, 0 };

// 异步 work 执行的回调
void execute(napi_env env, void* data) {
    struct promiseInfo *arg = (struct promiseInfo *)data; 
    arg->val = "success";
}

// 异步 work 执行结束时,调用的回调
void complete(napi_env env, napi_status status, void *data) {
    struct promiseInfo *arg = (struct promiseInfo *)data; 
    napi_value val; 
    if (true) { 
        // 执行 reslove 操作
        napi_create_string_utf8(env, arg->val, NAPI_AUTO_LENGTH, &val); 
        napi_resolve_deferred(env, arg->deferred, val);
    } else {
        // 执行 reject 操作
        napi_create_string_utf8(env, "error", NAPI_AUTO_LENGTH, &val);
        napi_reject_deferred(env, arg->deferred, val);
    }
    napi_delete_async_work(env, arg->worker); 
    arg->deferred = nullptr;
}

static napi_value getPromise(napi_env env, napi_callback_info info)
{
    napi_value promise;
    napi_value resourceName;
    struct promiseInfo *ptr = &data;
    // 创建新的的延迟对象 deferred 与延迟对象相关联的 JavaScript promise。
    napi_create_promise(env, &ptr->deferred, &promise);
    napi_create_string_utf8(env, "test", NAPI_AUTO_LENGTH, &resourceName);

    // 创建异步 work
    napi_create_async_work(env, nullptr, resourceName, execute, complete, ptr, &ptr->worker);
    // 把异步 work 放到队列中,等待执行
    napi_queue_async_work(env, ptr->worker);
    return promise;
}

场景2:C++ 侧使用从 JS 侧获取的 Promise 实例

JS 侧

调用 handlePromise,传入返回值是 promise 实例的函数

Row() {
	Text("handlePromise")
		.fontSize(50)
		.fontWeight(FontWeight.Bold)
		.onClick(() => {
			let res = testNapi.handlePromise(()=>{
				return new Promise((resolve, reject) => {
					let v = "resolve success";
					resolve(v);
				})
			})
			hilog.info(0x0000, 'testTag', 'Test NAPI handlePromise res is %{public}s', JSON.stringify(res))
		})
}
C++ 侧

1、接收 从 JS 侧传来的函数参数。 2、调用函数,得到返回值,一个 promise 实例。 3、获取 promise 实例的 then、catch 属性方法,并使用相应的函数参数进行调用。

// 创建 then 回调函数
auto successCb = [](napi_env env, napi_callback_info info) -> napi_value {
    size_t argc = 1;
    napi_value args[1] = { nullptr };
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    char v[20];
    size_t res;
    napi_get_value_string_utf8(env, args[0], v, 20, &res);
    return nullptr;
};

// 创建 catch 回调函数
auto errorCb= [](napi_env env, napi_callback_info info) -> napi_value {
    size_t argc = 1;
    napi_value args[1] = { nullptr };
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    char v[20];
    size_t res;
    napi_get_value_string_utf8(env, args[0], v, 20, &res);
    return nullptr;
};

static napi_value handlePromise(napi_env env, napi_callback_info info) {
    size_t argsNum = 1;
    napi_value args[1] = { nullptr };
    napi_value context;
    napi_get_cb_info(env, info, &argsNum, args, &context, nullptr);
  
    napi_value promise;
    // c++ 侧调用从 JS 侧传参过来的函数,函数返回值是一个 Promise 实例
    napi_call_function(env, context, args[0], 0, nullptr, &promise);

    // promiseThen = promise.then,把 promise 实例的 then 属性地址赋值给 promiseThen
    napi_value promiseThen;
    napi_get_named_property(env, promise, "then", &promiseThen);

    // promiseCatch = promise.catch
    napi_value promiseCatch;
    napi_get_named_property(env, promise, "catch", &promiseCatch);

    // then 回调函数转换成 N-API value 类型
    napi_value successFunc;
    napi_create_function(env, "successFunc", NAPI_AUTO_LENGTH, successCb, nullptr, &successFunc);

    // catch 回调函数转换成 N-API value 类型
    napi_value errorFunc;
    napi_create_function(env, "errorFunc", NAPI_AUTO_LENGTH, errorCb, nullptr, &errorFunc);
    
    napi_value ret;
    // 执行 promiseThen(successCb),相当于 promise.then(() => {}) 
    napi_call_function(env, promise, promiseThen, 1, &successFunc, &ret);

    // 执行 promiseCatch(errorCb),相当于 promise.catch(() => {}) 
 		napi_call_function(env, promise, promiseCatch, 1, &errorFunc, &ret);
    return context;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值