各位码友们好!今天这篇干货主要聚焦实操细节,希望能帮大家少踩坑。
要是过程中遇到哪块没看懂、有疑问,或者你有更优的实现思路,评论区尽管聊!发现文档里有疏漏或错误也尽管指出来 ——
技术这东西就得互相挑刺才能越磨越精,咱们一起把这些知识点吃透~
是什么?
- 与同步处理相对,异步处理不用阻塞当前线程来等待处理完成,而是允许后续操作,直至其它线程将处理完成,并回调通知此线程。---百度百科。
- 用更加通俗的话说,举个例子,你去蛋糕店定做一个蛋糕。
- 同步方式就是,你去蛋糕店告诉老板说你要一个蛋糕,然后老板开始做蛋糕,你就在店里等着,等老板做完,你带走蛋糕。
- 异步就是,你去蛋糕店告诉老板说你要一个蛋糕,老板开始做蛋糕,你可以去逛街去购物,去做其他事情;老板做完蛋糕打电话给你,你过去把蛋糕拿回来。
- 异步不会卡住当前线程,当前线程创建好异步任务就去干别的事情了,等异步任务完成在回来处理执行结果。
为什么?
- 主要目的就一个,为了让我们的应用更加丝滑流畅,不卡顿。
- HarmonyOS NEXT系统丝滑流畅,异步编程有着很大功劳。查阅HarmonyOS的API文档会发现很多耗时的API都是异步的。
- 并且OpenHarmony的API设计规范里面也有一条这样的说明:
应及时响应,避免调用者等待;如果API调用执行时间过长应设计为异步方式
。
- 在需要执行耗时操作的场景中使用,避免阻塞env所在的ArkTS线程,确保应用程序的性能和响应性能。例如以下场景:
- 文件操作:读取大型文件或执行复杂的文件操作时,可以使用异步工作对象来避免阻塞env所在的ArkTS线程。
- 网络请求:当需要进行网络请求并等待响应时,使用异步工作对象确保主线程不被阻塞,提高应用程序的响应性能。
- 数据库操作:当需要执行复杂的数据库查询或写入操作时,使用异步工作对象确保主线程不被阻塞,提高应用程序的并发性能。
- 图像处理:当需要对大型图像进行处理或执行复杂的图像算法时,使用异步工作对象确保主线程不被阻塞,提高应用程序的实时性能。--- 华为开发者官网。
怎么做?
- 华为官网这篇文章已经讲的非常透彻了,建议大家收藏本文之后,先学习华为官网这篇文章:使用Node-API接口进行异步任务开发
- 我在补充一些经验,帮大家避坑。
不要在napi_create_async_work的execute回调中使用env变量
napi_status napi_create_async_work(napi_env env,napi_value async_resource,napi_value async_resource_name,napi_async_execute_callback execute,napi_async_complete_callback complete,void* data,napi_async_work* result);
execute函数应该避免进行任何可能导致执行JavaScript或与JavaScript对象交互的Node-API调用。大多数情况下,任何需要进行Node-API调用的代码都应该在complete回调中进行。避免在execute回调中使用napi_env参数,因为它可能会执行JavaScript。
不应该在complete回调中执行耗时任务
complete
回调是用于将C++侧的结果转为js返回给应用。这个回调是在主线程中执行的,如果里面有耗时任务,则会占用主线程,导致出现应用卡住等问题,影响用户体验。- 所以建议
complete
里面只做语言类型的转换,不要有其他逻辑,其他逻辑尽可能放到execute
中执行。
做好资源管理,避免泄漏
- 我们存储上下文信息的
data
会被跨线程传递,所以不能使用栈内存,一定要申请动态内存。 - 通常在调用
napi_create_async_work
创建异步任务之前,就应该申请好了data
内存。 - 然后在执行
execute
回调时,data
会被传递过去,用于存放C++侧的上下文信息。 - 接着执行
complete
时,也能够拿到data
,我们就可以从data
中取出C++的执行结果,然后转化成js语言。 - 最后一定记得在
complete
回调中释放data
内存,同时调用napi_delete_async_work
删除异步任务。
在complete回调被调用之前,不应该删除napi_async_work
napi_status napi_cancel_async_work(node_api_basic_env env,napi_async_work work);
这个API会取消尚未执行的排队中的异步任务。如果任务已经开始执行,则不能取消,并且返回napi_generic_failure。如果成功,将调用complete回调,napi_status值为napi_cancelled。在完成complete回调之前,不应该删除napi_async_work,即使它已成功取消。
参考资料:
使用Node-API接口进行异步任务开发
Simple asynchronous operations
历史文章
1【鸿蒙/OpenHarmony/NDK】C/C++开发教程之环境搭建
2【鸿蒙/OpenHarmony/NDK】什么是NDK? 为啥要用NDK?
3【鸿蒙/OpenHarmony/NDK】如何在鸿蒙应用中使用NDK?
4【鸿蒙/OpenHarmony/NDK】如何在鸿蒙Navite C++样例代码中新增一个js接口?