1# Working with Task Queues Using JSVM-API 2 3## Introduction 4 5JSVM-API provides APIs for processing and dispatching the tasks that are queued up for execution. You can use the APIs to start the running of a task queue in a JSVM and check whether there are micro tasks waiting in the queue. The task queue can be executed cyclically by external events. 6 7## Basic Concepts 8 9- Task queue: a mechanism used to manage the scheduling and execution of asynchronous tasks to ensure that tasks are processed in sequence. 10- Micro task: a small task that needs to be executed as soon as possible. Micro tasks usually have a higher priority. 11 12## Available APIs 13 14| API| Description| 15| -------- | -------- | 16|OH_JSVM_PumpMessageLoop| Starts running a task queue.| 17|OH_JSVM_PerformMicrotaskCheckpoint| Executes micro tasks in a task queue.| 18## Example 19 20If you are just starting out with JSVM-API, see [JSVM-API Development Process](use-jsvm-process.md). The following demonstrates only the C++ code involved in task queue development. 21 22### OH_JSVM_PumpMessageLoop and OH_JSVM_PerformMicrotaskCheckpoint 23 24Use **OH_JSVM_PumpMessageLoop** to start running a task queue. 25 26CPP code: 27 28```cpp 29#include "ark_runtime/jsvm.h" 30#include <cassert> 31#include <string.h> 32#include "hilog/log.h" 33#include <unistd.h> 34#undef LOG_TAG 35#define LOG_TAG "log" 36#undef LOG_DOMAIN 37#define LOG_DOMAIN 0x1 38 39// JS code to be executed. 40static const char *STR_TASK = R"JS( 41 // Wasm bytecode (using the add module as an example) 42 // The following is the text format of the Wasm bytecode corresponding to wasmBuffer, which contains only the add function. 43 // (module 44 // (func $add (param $lhs i32) (param $rhs i32) (result i32) 45 // local.get $lhs 46 // local.get $rhs 47 // i32.add 48 // ) 49 // (export "add" (func $add)) 50 // ) 51 var wasmBytes = new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 52 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, 53 0x07, 0x01, 0x03, 0x61, 0x64, 0x64, 0x00, 0x00, 0x0a, 0x09, 0x01, 54 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b]); 55 56 var p = WebAssembly.instantiate(wasmBytes, {}); 57 p.then((result) => { 58 consoleinfo("Called with instance " + result); 59 }); 60 p.finally(() => { 61 consoleinfo("Called Finally"); 62 }); 63)JS"; 64 65// Ensure normal printing of the JS code information. 66static JSVM_Value ConsoleInfo(JSVM_Env env, JSVM_CallbackInfo info) { 67 size_t argc = 1; 68 JSVM_Value args[1]; 69 char log[256] = ""; 70 size_t logLength; 71 JSVM_CALL(OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL)); 72 73 OH_JSVM_GetValueStringUtf8(env, args[0], log, 255, &logLength); 74 log[255] = 0; 75 OH_LOG_INFO(LOG_APP, "JSVM API TEST: %{public}s", log); 76 return nullptr; 77} 78 79// Register the consoleinfo callback. 80JSVM_CallbackStruct param[] = { 81 {.data = nullptr, .callback = ConsoleInfo}, 82}; 83JSVM_PropertyDescriptor descriptor[] = { 84 {"consoleinfo", NULL, ¶m[0], NULL, NULL, NULL, JSVM_DEFAULT}, 85}; 86 87static int32_t TestJSVM() { 88 JSVM_InitOptions init_options; 89 memset(&init_options, 0, sizeof(init_options)); 90 if (g_aa == 0) { 91 OH_JSVM_Init(&init_options); 92 g_aa++; 93 } 94 // Create a JSVM instance and open the VM scope. 95 JSVM_VM vm; 96 JSVM_CreateVMOptions options; 97 memset(&options, 0, sizeof(options)); 98 CHECK(OH_JSVM_CreateVM(&options, &vm) == JSVM_OK); 99 JSVM_VMScope vm_scope; 100 CHECK(OH_JSVM_OpenVMScope(vm, &vm_scope) == JSVM_OK); 101 102 JSVM_Env env; 103 CHECK(OH_JSVM_CreateEnv(vm, sizeof(descriptor) / sizeof(descriptor[0]), descriptor, &env) == JSVM_OK); 104 JSVM_EnvScope envScope; 105 CHECK_RET(OH_JSVM_OpenEnvScope(env, &envScope)); 106 JSVM_HandleScope handlescope; 107 CHECK_RET(OH_JSVM_OpenHandleScope(env, &handlescope)); 108 JSVM_Value sourcecodevalue; 109 CHECK_RET(OH_JSVM_CreateStringUtf8(env, STR_TASK, strlen(STR_TASK), &sourcecodevalue)); 110 JSVM_Script script; 111 CHECK_RET(OH_JSVM_CompileScript(env, sourcecodevalue, nullptr, 0, true, nullptr, &script)); 112 JSVM_Value result; 113 CHECK_RET(OH_JSVM_RunScript(env, script, &result)); 114 bool rst = false; 115 auto start = std::chrono::system_clock::now(); 116 while (true) { 117 // If no task is started in the task queue, set rst to false. 118 CHECK_RET(OH_JSVM_PumpMessageLoop(vm, &rst)); 119 CHECK_RET(OH_JSVM_PerformMicrotaskCheckpoint(vm)); 120 // Exit at the scheduled time. 121 auto now = std::chrono::system_clock::now(); 122 auto cost = std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count(); 123 if (cost > 100) { 124 break; 125 } 126 } 127 128 // Close and destroy the environment and the VM. 129 CHECK_RET(OH_JSVM_CloseHandleScope(env, handlescope)); 130 CHECK_RET(OH_JSVM_CloseEnvScope(env, envScope)); 131 CHECK(OH_JSVM_DestroyEnv(env) == JSVM_OK); 132 CHECK(OH_JSVM_CloseVMScope(vm, vm_scope) == JSVM_OK); 133 CHECK(OH_JSVM_DestroyVM(vm) == JSVM_OK); 134 return 0; 135} 136 137``` 138