首页 > 其他分享 >Openharmony应用NAPI详解--进阶篇2

Openharmony应用NAPI详解--进阶篇2

时间:2023-04-23 11:37:09浏览次数:54  
标签:status Openharmony -- create value 进阶篇 promise env napi

NAPI面向C++的异步接口(promise)

promise方式的处理方式

承接上文,与callback方式不同的是,promise对象由C++侧创建以返回值的方式传递回js/ets侧,promise对象存储异步执行的结果。

// foundation/filemanagement/file_api/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.cpp
NVal NAsyncWorkPromise::Schedule(string procedureName, NContextCBExec cbExec, NContextCBComplete cbComplete)
{
    ctx_->cbExec_ = move(cbExec);
    ctx_->cbComplete_ = move(cbComplete);

    napi_status status;
    napi_value result = nullptr;
    status = napi_create_promise(env_, &ctx_->deferred_, &result);
    if (status != napi_ok) {
        HILOGE("INNER BUG. Cannot create promise for %{public}d", status);
        return NVal();
    }

    napi_value resource = NVal::CreateUTF8String(env_, procedureName).val_;
    status = napi_create_async_work(env_, nullptr, resource, PromiseOnExec, PromiseOnComplete, ctx_, &ctx_->awork_);
    if (status != napi_ok) {
        HILOGE("INNER BUG. Failed to create async work for %{public}d", status);
        return NVal();
    }

    status = napi_queue_async_work(env_, ctx_->awork_);
    if (status != napi_ok) {
        HILOGE("INNER BUG. Failed to queue async work for %{public}d", status);
        return NVal();
    }

    ctx_ = nullptr; // The ownership of ctx_ has been transfered
    return { env_, result };
}

1.napi_create_promise创建创建Promise,返回promise、deferred 二个对象, promise用于主线程方法返回。 deferred对象用于resolve、reject处理。

首先先分析下napi_create_promise的方法定义

napi_status napi_create_promise(napi_env env,
                                napi_deferred* deferred,
                                napi_value* promise);

参数说明:

  • [in] env: 传入接口调用者的环境,包含js引擎等,由框架提供,默认情况下直接传入即可。
  • [out] deferred: 返回接收刚创建的deferred对象,关联Promise对象,后面用于napi_resolve_deferred() 或 napi_reject_deferred() 更新状态,返回数据。
  • [out] promise: 关联上面deferred对象的JS Promise对象,用于主线程方法返回。 返回值:返回napi_ok表示转换成功,其他值失败。

2.执行napi_create_async_work异步线程后,将deferred对象,通过napi_queue_async_work将创建的async work添加到队列,由NAPI框架的底层去调度后执行。

3.result即为返回的promise对象。

napi_create_async_work中的异步处理execute和complete方法,分别对应PromiseOnExec, PromiseOnComplete。处理完成后将ctx->res_结果更新至deferred的对象中。

static void PromiseOnExec(napi_env env, void *data)
{
...
}

static void PromiseOnComplete(napi_env env, napi_status status, void *data)
{
...
    if (!ctx->res_.TypeIsError(true)) {
        napi_status status = napi_resolve_deferred(env, ctx->deferred_, ctx->res_.val_);
        if (status != napi_ok) {
            HILOGE("Internal BUG, cannot resolve promise for %{public}d", status);
        }
    } else {
        napi_status status = napi_reject_deferred(env, ctx->deferred_, ctx->res_.val_);
        if (status != napi_ok) {
            HILOGE("Internal BUG, cannot reject promise for %{public}d", status);
        }
    }
    ctx->deferred_ = nullptr;
    napi_delete_async_work(env, ctx->awork_);
    delete ctx;
}

最终返回临时结果NVal给js调用 (callback接口返回的是void, promise接口返回的是返回临时结果给js调用)。

此文讲解NAPI选用的分布式文件子系统,此实例将NAPI的接口封装成了多个操作的类(NAsyncWorkPromise、NAsyncWorkCallback、NVal等),对JS如何通过NAPI的调用C++调用流程与使用方式有一定的了解。如果想了解更多的NAPI的使用细节,可以在Openharmony的其它的子系统中查看其它的NAPI方法。以下提供NAPI的其它的一些接口说明和注意事项。

NAPI类型与接口说明

typedef enum {
  napi_undefined,
  napi_null,
  napi_boolean,
  napi_number,
  napi_string,
  napi_symbol,
  napi_object,
  napi_function,
  napi_external,
  napi_bigint
} napi_valuetype;
//对应了ECMAScript标准中定义的Undefined、Null、Boolean、Number、String、Symbol、Object、Function和BigInt九种数据类型。另外,napi_valuetype还包括了一个napi_external类型,其表示没有任何属性也没有任何原型的对象。

napi_status napi_get_value_double(
  napi_env env,
  napi_value value,     // 获取的Javascript值
  double *result        // 用于保存对应的double类型值
);

// napi_create_double创建其对应的Javascript double值result
napi_status napi_create_double(
  napi_env env,
  double value,         // double类型的值
  napi_value *result    // 保存创建的Javascript值
);

// napi_create_string_utf8用于创建一个UTF-8类型的字符串对象,其值来自于参数传递的UTF-8编码字符串
napi_status napi_create_string_utf8(napi_env env,
  const char *str,
  size_t length,
  napi_value* result
);

napi_status napi_get_value_double(
  napi_env env,
  napi_value value,     // 获取的Javascript值
  double *result        // 用于保存对应的double类型值
);

// napi_create_double创建其对应的Javascript double值result
napi_status napi_create_double(
  napi_env env,
  double value,         // double类型的值
  napi_value *result    // 保存创建的Javascript值
);

// napi_create_string_utf8用于创建一个UTF-8类型的字符串对象,其值来自于参数传递的UTF-8编码字符串
napi_status napi_create_string_utf8(napi_env env,
  const char *str,
  size_t length,
  napi_value* result
);

// C/C++类型转NAPI类型
napi_status napi_create_object(napi_env env, napi_value *value);
napi_status napi_create_array(napi_env env, napi_value* value);

//异步方法需要在不同线程中传递各种业务数据,定义一个结构体保存这些被传递的信息
struct MyAsyncContext {
    napi_env env = nullptr; // napi运行环境
    napi_async_work work = nullptr; // 异步工作对象
    napi_deferred deferred = nullptr; // 延迟执行对象(用于promise方式返回计算结果)
    napi_ref callbackRef = nullptr; // js callback function的引用对象 (用于callback方式返回计算结果)
    int32_t status;
    napi_value value[3];
};

其它一些API参考官方文档:

https://www.apiref.com/nodejs-zh/n-api.html

注意事项

1.回调函数callback字段使用napi_ref类型,不能使用napi_value类型。因napi_value类型对象生命周期在原生方法结束时结束,导致在work线程、EventLoop线程中获取不到,而napi_ref类型生命周期大于方法的。

2.NAPI在Openharmony的V3.2版本之后,添加了NAPI框架生成工具(napi_generator)子系统,故名思义,可以自动生成NAPI的框架,后续如果有读者对此有兴趣,可以专门开辟篇章进行说明。

后续更精彩

1.关于service ability的前世今生

2.L0设备在Openharmony基座上的开发实例

3.鸿蒙编译构建流程

标签:status,Openharmony,--,create,value,进阶篇,promise,env,napi
From: https://blog.51cto.com/u_15304012/6216908

相关文章

  • sql注入getshell的几种方式
    文章目录一.intooutfile利用条件写入webshell二.--os-shell--sql-shell    介绍几种利用sql注入获取系统权限的方法,一是利用outfile函数,另外一种是利用--os-shell。一.intooutfile  利用条件:    1.此方法利用的先决条件web目录具有写权限,能够......
  • 如何在交互式环境中执行Python程序
    相信接触过Python的小伙伴们都知道运行Python脚本程序的方式有多种,目前主要的方式有:交互式环境运行、命令行窗口运行、开发工具上运行等,其中在不同的操作平台上还互不相同。今天,小编讲些Python基础的内容,以Windows下交互式环境为依托,演示Python程序的运行。一般来说,顺利安装Python......
  • uiautomator2+app ui自动化用例报错截图pytest_runtest_makereport
    pytest提供了pytest_runtest_makereport这个方法,可以捕获用例的执行情况。根据官方提供的示例,在conftest.py文件中添加如下代码就可以捕获每个用例的执行结果。那么pytest_runtest_makereport作用:对于给定的测试用例(item)和调用步骤(call),返回一个测试报告对象(_pytest.runne......
  • 为什么单片机编程放不下超过32万的整数?
    因为你的单片机可能是16位的,c语言16位编译器的int类型占2字节,也就是范围:-2^15~2^15-1 (-32768~32767)。32位的编译器int类型占4字节。这种情况下可以使用longint(16位编译器4字节),也可以使用循环处理整数。 ......
  • 手把手教你进行Scrapy中item类的实例化操作
     接下来我们将在爬虫主体文件中对Item的值进行填充。1、首先在爬虫主体文件中将Item模块导入进来,如下图所示。2、第一步的意思是说将items.py中的ArticleItem类导入到爬虫主体文件中去,将两个文件串联起来,其中items.py的部分内容如下图所示。3、将这个ArticleItem类导入之后,接下来......
  • 多通道振弦传感器无线采集仪 多类型数字传感器独立发送协议
    河北稳控科技多通道振弦传感器无线采集仪多类型数字传感器独立发送协议 独立发送传感器数据时,每个传感器是一个独立的数据包,发送至预设的TCP服务器。数据包字符串,结构说明如下:UDID>MDS+传感器类型码+第x个传感器>第x包/总x包>传感器数据,校验和字符,回车换行符例如:“......
  • 手把手教你使用Python网络爬虫获取菜谱信息
    今日鸡汤一腔热血勤珍重,洒去犹能化碧涛。/1前言/    在放假时,经常想尝试一下自己做饭,下厨房这个网址是个不错的选择。    下厨房是必选的网址之一,主要提供各种美食做法以及烹饪技巧。包含种类很多。    今天教大家去爬取下厨房的菜谱,保存在world文档,方便日后制作自......
  • 可视化大屏的终极解决方案居然这么简单,vue-autofit一行全搞定!
    可视化大屏适配/自适应现状可视化大屏的适配是一个老生常谈的话题了,现在其实不乏一些大佬开源的自适应插件、工具但是我为什么还要重复造轮子呢?因为目前市面上适配工具每一个都无法做到完美的效果,做出来的东西都差不多,最终实现效果都逃不出白边的手掌心,可以解决白边问题的,要么太......
  • 力扣844(Java)-比较含退格的字符串(简单)
    题目:给定s和t两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回true。#代表退格字符。注意:如果对空文本输入退格字符,文本继续为空。 示例1:输入:s="ab#c",t="ad#c"输出:true解释:s和t都会变成"ac"。示例2:输入:s="ab##",t="c#d#"输出:true......
  • 06期:使用 OPTIMIZER_TRACE 窥探 MySQL 索引选择的秘密
    这里记录的是学习分享内容,文章维护在Github:studeyang/leanrning-share。优化查询语句的性能是MySQL数据库管理中的一个重要方面。在优化查询性能时,选择正确的索引对于减少查询的响应时间和提高系统性能至关重要。但是,如何确定MySQL的索引选择策略?MySQL的优化器是如何选择索......