• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用JSVM-API接口进行任务队列相关开发
2
3## 简介
4
5在虚拟机内部启动任务队列的运行,检查是否有微任务在队列中等待,这个任务队列可以由外部事件循环执行。
6
7## 基本概念
8
9- **任务队列**:管理异步任务的调度和执行,确保任务按顺序处理。
10- **微任务**:微任务是一种任务调度机制,主要用于处理那些需要尽快执行的较小任务,它们通常具有较高的优先级。
11
12## 接口说明
13
14| 接口 | 功能说明 |
15| -------- | -------- |
16|OH_JSVM_PumpMessageLoop| 启动任务队列的运行 |
17|OH_JSVM_PerformMicrotaskCheckpoint| 执行任务队列里的微任务 |
18## 使用示例
19
20JSVM-API接口开发流程参考[使用JSVM-API实现JS与C/C++语言交互开发流程](use-jsvm-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。
21
22### OH_JSVM_PumpMessageLoop && OH_JSVM_PerformMicrotaskCheckpoint
23
24启动任务队列,执行任务。
25
26cpp代码
27
28```cpp
29#include "napi/native_api.h"
30#include "ark_runtime/jsvm.h"
31#include <cassert>
32#include <string.h>
33#include "hilog/log.h"
34#include "napi/native_api.h"
35#include <unistd.h>
36#undef  LOG_TAG
37#define LOG_TAG "log"
38#undef  LOG_DOMAIN
39#define LOG_DOMAIN 0x1
40
41//全局变量,保证虚拟机只初始化一次
42static int aa = 0;
43
44//待执行的js代码
45static const char *STR_TASK = R"JS(
46new Promise((resolve,reject) => {
47    resolve(1)
48})
49.then(function(obj) {
50    consoleinfo("Called with instance " + obj);
51}).catch(function(err) {
52    consoleinfo("Called with error ");
53});
54)JS";
55
56//保证js代码中的打印信息可以正常输出
57static JSVM_Value ConsoleInfo(JSVM_Env env, JSVM_CallbackInfo info) {
58    size_t argc = 1;
59    JSVM_Value args[1];
60    char log[256] = "";
61    size_t logLength;
62    OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL);
63
64    OH_JSVM_GetValueStringUtf8(env, args[0], log, 255, &logLength);
65    log[255] = 0;
66    OH_LOG_INFO(LOG_APP, "JSVM API TEST: %{public}s", log);
67    return nullptr;
68}
69
70//启动任务队列里的任务并执行
71static napi_value testHandleMicrotasks(napi_env env1, napi_callback_info info)
72{
73    JSVM_InitOptions init_options;
74    memset(&init_options, 0, sizeof(init_options));
75    if (aa == 0) {
76        OH_JSVM_Init(&init_options);
77        aa++;
78    }
79    // 创建JavaScript虚拟机实例,打开虚拟机作用域
80    JSVM_VM vm;
81    JSVM_CreateVMOptions options;
82    memset(&options, 0, sizeof(options));
83    OH_JSVM_CreateVM(&options, &vm);
84    JSVM_VMScope vm_scope;
85    OH_JSVM_OpenVMScope(vm, &vm_scope);
86    // 注册consoleinfo的方法
87    JSVM_CallbackStruct param[] = {
88        {.data = nullptr, .callback = ConsoleInfo},
89    };
90    JSVM_PropertyDescriptor descriptor[] = {
91        {"consoleinfo", NULL, &param[0], NULL, NULL, NULL, JSVM_DEFAULT},
92    };
93    JSVM_Env env;
94    OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env);
95    JSVM_EnvScope envScope;
96    OH_JSVM_OpenEnvScope(env, &envScope);
97    JSVM_HandleScope handlescope;
98    OH_JSVM_OpenHandleScope(env, &handlescope);
99    JSVM_Value sourcecodevalue;
100    OH_JSVM_CreateStringUtf8(env, STR_TASK, strlen(STR_TASK), &sourcecodevalue);
101    JSVM_Script script;
102    OH_JSVM_CompileScript(env, sourcecodevalue, nullptr, 0, true, nullptr, &script);
103    JSVM_Value result;
104    OH_JSVM_RunScript(env, script, &result);
105    bool rst = false;
106    for (int i = 0; i < 3; i++) { // 3: cycles
107        //如果消息队列中没有任务启动,则rst设置为false。
108        JSVM_Status flag1 = OH_JSVM_PumpMessageLoop(vm, &rst);
109        JSVM_Status flag2 = OH_JSVM_PerformMicrotaskCheckpoint(vm);
110        if (rst && flag1 == JSVM_Status::JSVM_OK && flag2 == JSVM_Status::JSVM_OK) {
111               sleep(3);
112               break;
113        }
114    }
115    // 关闭并销毁环境和虚拟机
116    OH_JSVM_CloseHandleScope(env, handlescope);
117    OH_JSVM_CloseEnvScope(env, envScope);
118    OH_JSVM_DestroyEnv(env);
119    OH_JSVM_CloseVMScope(vm, vm_scope);
120    OH_JSVM_DestroyVM(vm);
121    //将OH_JSVM_PumpMessageLoop执行后返回的结果转换为布尔类型输出
122    napi_value result11;
123    napi_status status = napi_get_boolean(env1, rst, &result11);
124    assert(status == napi_ok);
125    return result11;
126}
127
128EXTERN_C_START
129static napi_value Init(napi_env env, napi_value exports)
130{
131    napi_property_descriptor desc[] = {
132        { "HandleMicrotasks", nullptr, testHandleMicrotasks, nullptr, nullptr, nullptr, napi_default, nullptr }
133    };
134    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
135    return exports;
136}
137EXTERN_C_END
138
139static napi_module demoModule = {
140    .nm_version = 1,
141    .nm_flags = 0,
142    .nm_filename = nullptr,
143    .nm_register_func = Init,
144    .nm_modname = "entry",
145    .nm_priv = ((void*)0),
146    .reserved = { 0 },
147};
148
149extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
150{
151    napi_module_register(&demoModule);
152}
153```
154
155ArkTS侧示例代码
156
157```ts
158import { hilog } from '@kit.PerformanceAnalysisKit';
159import testNapi from 'libentry.so';
160
161@Entry
162@Component
163struct Index {
164  @State message: string = 'Perform task';
165
166  build() {
167    Row() {
168      Column() {
169        Text(this.message)
170          .fontSize(50)
171          .fontWeight(FontWeight.Bold)
172          .onClick(() => {
173            let result = testNapi.HandleMicrotasks();
174            console.info("任务队列是否启动任务:"+result);
175
176          })
177      }
178      .width('100%')
179    }
180    .height('100%')
181  }
182}
183```
184