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, ¶m[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