diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc index a61038398dde4a2caf40b949197f3c2fbf4108b5..6749348a1fd788e34af5ab2d3de5ad99eb474156 100644 --- a/src/js_native_api_v8.cc +++ b/src/js_native_api_v8.cc @@ -1836,6 +1836,48 @@ class CompileOptionResolver { bool hasInvalidOption = false; }; +JSVM_Status JSVM_CDECL OH_JSVM_PromiseRegisterHandler( + JSVM_Env env, JSVM_Value promise, JSVM_Value onFulfilled, JSVM_Value onRejected, JSVM_Value *result) +{ + JSVM_PREAMBLE(env); + CHECK_ARG(env, promise); + RETURN_STATUS_IF_FALSE(env, onFulfilled || onRejected, JSVM_INVALID_ARG); + + v8::Local value = v8impl::V8LocalValueFromJsValue(promise); + RETURN_STATUS_IF_FALSE(env, value->IsPromise(), JSVM_INVALID_TYPE); + auto localPromise = value.As(); + + v8::Local ctx = env->context(); + v8::MaybeLocal maybe; + if (!onFulfilled) { + // Only pass onRejected, call v8::Promise::Catch + auto rejectedHandler = v8impl::V8LocalValueFromJsValue(onRejected); + RETURN_STATUS_IF_FALSE(env, rejectedHandler->IsFunction(), JSVM_INVALID_TYPE); + maybe = localPromise->Catch(ctx, rejectedHandler.As()); + } else if (!onRejected) { + // Only pass onFulfilled, call v8::Promise::Then + auto fulfiledHandler = v8impl::V8LocalValueFromJsValue(onFulfilled); + RETURN_STATUS_IF_FALSE(env, fulfiledHandler->IsFunction(), JSVM_INVALID_TYPE); + maybe = value.As()->Then(ctx, fulfiledHandler.As()); + } else { + // Pass onFulfilled and onRejected, call v8::Promise::Then + auto fulfiledHandler = v8impl::V8LocalValueFromJsValue(onFulfilled); + RETURN_STATUS_IF_FALSE(env, fulfiledHandler->IsFunction(), JSVM_INVALID_TYPE); + auto rejectedHandler = v8impl::V8LocalValueFromJsValue(onRejected); + RETURN_STATUS_IF_FALSE(env, rejectedHandler->IsFunction(), JSVM_INVALID_TYPE); + maybe = value.As()->Then(ctx, fulfiledHandler.As(), rejectedHandler.As()); + } + + CHECK_MAYBE_EMPTY_WITH_PREAMBLE(env, maybe, JSVM_GENERIC_FAILURE); + + if (result) { + auto retPromise = maybe.ToLocalChecked(); + *result = v8impl::JsValueFromV8LocalValue(retPromise); + } + + return jsvm_clear_last_error(env); +} + size_t CompileOptionResolver::compileCount = 0; JSVM_Status JSVM_CDECL diff --git a/src/jsvm.h b/src/jsvm.h index 41a7f81f32df13a16233bcaffd4f2f419929a7ea..a6e82099f63e75790389d1def7c526bff6621db8 100644 --- a/src/jsvm.h +++ b/src/jsvm.h @@ -2189,6 +2189,28 @@ JSVM_EXTERN JSVM_Status OH_JSVM_IsPromise(JSVM_Env env, JSVM_Value value, bool* isPromise); +/** + * @brief This API register a resolution/rejection handler with a promise. + * @param env The environment that the API is invoked under. + * @param promise The promise to be handled. + * @param onFulfilled The function to be invoked if promise is resolved. + * @param onRejected The function to be invoked if promise is rejected. + * @param result Another promise returned from promise then/catch method. + * @return Returns JSVM functions result code. + * {@link JSVM_OK } if the API succeeded. \n + * {@link JSVM_INVALID_ARG } if the arguments are invalid. \n + * {@link JSVM_INVALID_TYPE } if the arguments are invalid Javascript type. \n + * {@link JSVM_PENDING_EXCEPTION} if an exception occurs. \n + * {@link JSVM_GENERIC_FAILURE} if the API failed. \n + * + * @since 16 + */ +JSVM_EXTERN JSVM_Status OH_JSVM_PromiseRegisterHandler(JSVM_Env env, + JSVM_Value promise, + JSVM_Value onFulfilled, + JSVM_Value onRejected, + JSVM_Value* result); + /** * @brief This API parses a JSON string and returns it as value if successful. * @param env: The environment that the API is invoked under.