1# 使用JSVM-API接口处理异步操作 2 3## 简介 4 5使用JSVM-API接口处理异步操作。异步操作是指需要一定时间才能完成的操作,例如从网络下载数据或读取大型文件。与同步操作不同,异步操作不会阻塞主线程,而是会在后台执行。当异步操作完成后,事件循环将把它放入任务队列中,等待主线程空闲时执行。 6 7## 基本概念 8 9Promise是JavaScript中用来处理异步操作的对象,Promise有pending(待定)、fulfilled(已兑现)和rejected(已拒绝)三种状态,Promise的初始状态是pending,resolve函数可以使其状态从pending变为fulfilled(已兑现),reject函数可以使其状态从pending变为rejected(已拒绝),一旦兑现或拒绝Promise的状态将不能更改。下面是一些基本概念: 10 11- **同步**: 同步是指代码按照顺序一行一行地执行,每行代码的执行都会等待上一行代码执行完成后再继续执行。在同步执行中,如果某个操作需要花费较长时间,那么整个程序的执行就会被阻塞,直到该操作完成才能继续执行后续代码。 12- **异步**:异步是指任务可以同时执行,不需要等待上一个任务结束。在JavaScript中,常见的异步操作包括定时器、事件监听、网络请求等。异步任务不会阻塞后续任务的执行,而是通过回调函数或Promise对象来处理任务的结果。 13- **Promise**:Promise是一个JavaScript对象,用于处理异步操作。Promise作用于外部,通常通过then、catch和finally方法暴露给外部以添加自定义逻辑。 14- **deferred**:deferred是延迟对象,它可以与Promise对象关联,设置Promise的回调函数resolve和reject。deferred作用于内部,维护异步模型的状态并设置回调函数resolve和reject。 15- **resolve**:此函数可以将Promise的状态从pending(待定)改为fulfilled(已兑现),向resolve中传入的参数可以在Promise对象的then方法中获取。 16- **reject**:此函数可以将Promise的状态从pending(待定)改为rejected(已拒绝),向reject中传入的参数可以在Promise对象的catch方法中获取。 17 18这些基本概念在处理异步操作中非常重要,开发者需要通过适当的方法来处理异步操作,Promise可以链式调用多个异步操作,使代码清晰整洁,便于维护。JSVM-API提供的方法可以帮助开发者在JSVM模块中处理JavaScript中的异步操作。 19 20## 接口说明 21 22| 接口 | 功能说明 | 23|----------------------------|--------------------------------| 24| OH_JSVM_IsPromise | 查询Promise是否为Promise对象| 25| OH_JSVM_CreatePromise | 创建一个延迟对象和一个JavaScript promise| 26| OH_JSVM_ResolveDeferred | 通过与之关联的延迟对象来解析JavaScript promise| 27| OH_JSVM_RejectDeferred | 通过与之关联的延迟对象来拒绝JavaScript Promise| 28 29## 使用示例 30 31JSVM-API接口开发流程参考[使用JSVM-API实现JS与C/C++语言交互开发流程](use-jsvm-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。 32 33### OH_JSVM_IsPromise 34 35判断给定的JSVM_Value是否表示一个Promise对象。 36 37cpp部分代码 38 39```cpp 40// hello.cpp 41#include "napi/native_api.h" 42#include "ark_runtime/jsvm.h" 43#include <hilog/log.h> 44// IsPromise注册回调 45static JSVM_CallbackStruct param[] = { 46 {.data = nullptr, .callback = IsPromise}, 47}; 48static JSVM_CallbackStruct *method = param; 49// IsPromise方法别名,供JS调用 50static JSVM_PropertyDescriptor descriptor[] = { 51 {"isPromise", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 52}; 53// OH_JSVM_IsPromise的样例方法 54static JSVM_Value IsPromise(JSVM_Env env, JSVM_CallbackInfo info) 55{ 56 size_t argc = 1; 57 JSVM_Value args[1] = {nullptr}; 58 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 59 bool isPromise = false; 60 JSVM_Status status = OH_JSVM_IsPromise(env, args[0], &isPromise); 61 if (status != JSVM_OK) { 62 OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_IsPromise fail"); 63 } else { 64 OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_IsPromise success:%{public}d", isPromise); 65 } 66 JSVM_Value result = nullptr; 67 OH_JSVM_GetBoolean(env, isPromise, &result); 68 return result; 69} 70``` 71 72ArkTS侧示例代码 73 74```ts 75import hilog from "@ohos.hilog" 76// 通过import的方式,引入Native能力。 77import napitest from "libentry.so" 78let script: string = ` 79 let value = Promise.resolve(); 80 isPromise(value); 81 `; 82try { 83 let result = napitest.runJsVm(script); 84 hilog.info(0x0000, 'JSVM', 'IsPromise: %{public}s', result); 85} catch (error) { 86 hilog.error(0x0000, 'JSVM', 'IsPromise: %{public}s', error.message); 87} 88``` 89 90### OH_JSVM_CreatePromise 91 92OH_JSVM_CreatePromise用于创建一个Promise对象。 93 94### OH_JSVM_ResolveDeferred & OH_JSVM_RejectDeferred 95 96用于对Promise关联的deferred对象进行解析,OH_JSVM_ResolveDeferred将其从挂起状态转换为已兑现状态,OH_JSVM_RejectDeferred将其从挂起状态转换为已拒绝状态。 97 98cpp部分代码 99 100```cpp 101// hello.cpp 102#include "napi/native_api.h" 103#include "ark_runtime/jsvm.h" 104#include <hilog/log.h> 105// CreatePromise,ResolveRejectDeferred注册回调 106static JSVM_CallbackStruct param[] = { 107 {.data = nullptr, .callback = CreatePromise}, 108 {.data = nullptr, .callback = ResolveRejectDeferred}, 109}; 110static JSVM_CallbackStruct *method = param; 111// CreatePromise,ResolveRejectDeferred方法别名,供JS调用 112static JSVM_PropertyDescriptor descriptor[] = { 113 {"createPromise", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 114 {"resolveRejectDeferred", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, 115}; 116// OH_JSVM_CreatePromise、OH_JSVM_ResolveDeferred、OH_JSVM_RejectDeferred的样例方法 117static JSVM_Value CreatePromise(JSVM_Env env, JSVM_CallbackInfo info) 118{ 119 JSVM_Deferred defer = nullptr; 120 JSVM_Value promise = nullptr; 121 JSVM_Status status = OH_JSVM_CreatePromise(env, &defer, &promise); 122 bool isPromise = false; 123 JSVM_Value returnIsPromise = nullptr; 124 OH_JSVM_IsPromise(env, promise, &isPromise); 125 if (status != JSVM_OK) { 126 OH_LOG_ERROR(LOG_APP, "JSVM CreatePromise fail"); 127 } else { 128 OH_LOG_INFO(LOG_APP, "JSVM CreatePromise success:%{public}d", isPromise); 129 } 130 // 将布尔值转为可以返回的JSVM_Value 131 OH_JSVM_GetBoolean(env, isPromise, &returnIsPromise); 132 return returnIsPromise; 133} 134 135static JSVM_Value ResolveRejectDeferred(JSVM_Env env, JSVM_CallbackInfo info) 136{ 137 // 获得并解析参数 138 size_t argc = 3; 139 JSVM_Value args[3] = {nullptr}; 140 OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr); 141 // 第一个参数为向resolve传入的信息,第二个参数为向reject传入的信息,第三个参数为Promise的状态 142 bool status = false; 143 OH_JSVM_GetValueBool(env, args[2], &status); 144 // 创建Promise对象 145 JSVM_Deferred deferred = nullptr; 146 JSVM_Value promise = nullptr; 147 JSVM_Status createStatus = OH_JSVM_CreatePromise(env, &deferred, &promise); 148 if (createStatus != JSVM_OK) { 149 OH_JSVM_ThrowError(env, nullptr, "Create promise failed"); 150 return nullptr; 151 } 152 // 根据第三个参数设置resolve或reject 153 if (status) { 154 OH_JSVM_ResolveDeferred(env, deferred, args[0]); 155 OH_LOG_INFO(LOG_APP, "OH_JSVM_ResolveDeferred resolve"); 156 } else { 157 OH_JSVM_RejectDeferred(env, deferred, args[1]); 158 OH_LOG_INFO(LOG_APP, "OH_JSVM_RejectDeferred reject"); 159 } 160 JSVM_Value result = nullptr; 161 OH_JSVM_GetBoolean(env, true, &result); 162 return result; 163} 164``` 165 166ArkTS侧示例代码 167 168```ts 169import hilog from "@ohos.hilog" 170// 通过import的方式,引入Native能力。 171import napitest from "libentry.so" 172let createPromiseScript: string = `createPromise();`; 173let createPromiseresult = napitest.runJsVm(createPromiseScript); 174hilog.info(0x0000, 'JSVM', 'CreatePromise: %{public}s', createPromiseresult); 175// 这里传入的第三个参数,表示Promise已将其从挂起状态设置为已兑现状态 176let resolveScript: string = `resolveRejectDeferred('success','fail', true);`; 177let result = napitest.runJsVm(resolveScript); 178hilog.info(0x0000, 'JSVM', 'ResolveRejectDeferred: %{public}s', result); 179// 这里传入的第三个参数,表示Promise将其从挂起状态设置为已拒绝状态 180let rejectScript: string = `resolveRejectDeferred('success','fail', false);`; 181let rejectResult = napitest.runJsVm(rejectScript); 182hilog.info(0x0000, 'JSVM', 'ResolveRejectDeferred: %{public}s', rejectResult); 183``` 184