You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QuickJS中如何在Promise完成或拒绝时执行代码?

在QuickJS中为Promise设置then和catch回调

你已经通过JS_NewPromiseCapability创建了Promise和对应的resolve/reject函数,接下来可以通过以下步骤为这个Promise绑定then和catch回调:

1. 获取Promise原型上的then和catch方法

首先需要从Promise的原型对象上获取then和catch方法,代码如下:

// 获取Promise构造函数
JSValue promiseConstructor = JS_GetPropertyStr(ctx, JS_GetGlobalObject(ctx), "Promise");
// 获取Promise.prototype
JSValue promisePrototype = JS_GetPropertyStr(ctx, promiseConstructor, "prototype");
// 获取then方法
JSValue thenMethod = JS_GetPropertyStr(ctx, promisePrototype, "then");
// 获取catch方法
JSValue catchMethod = JS_GetPropertyStr(ctx, promisePrototype, "catch");

// 释放临时对象,避免内存泄漏
JS_FreeValue(ctx, promiseConstructor);
JS_FreeValue(ctx, promisePrototype);

2. 定义resolve和reject的回调函数

需要先实现QuickJS风格的回调函数,用于处理Promise的resolved和rejected状态:

// resolve回调:当Promise完成时触发
JSValue onResolved(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
    // argv[0]是Promise resolve时传入的值
    if (argc > 0) {
        const char *val = JS_ToCString(ctx, argv[0]);
        printf("Promise resolved with value: %s\n", val);
        JS_FreeCString(ctx, val);
    }
    return JS_UNDEFINED;
}

// reject回调:当Promise拒绝时触发
JSValue onRejected(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
    // argv[0]是Promise reject时传入的原因
    if (argc > 0) {
        const char *reason = JS_ToCString(ctx, argv[0]);
        printf("Promise rejected with reason: %s\n", reason);
        JS_FreeCString(ctx, reason);
    }
    return JS_UNDEFINED;
}

3. 为Promise绑定then和catch回调

把上面定义的回调函数作为参数,调用之前获取的then和catch方法:

// 创建resolve回调的JS函数对象
JSValue resolvedFunc = JS_NewCFunction(ctx, onResolved, "onResolved", 1);
// 创建reject回调的JS函数对象
JSValue rejectedFunc = JS_NewCFunction(ctx, onRejected, "onRejected", 1);

// 调用then方法:promise.then(onResolved, onRejected)
JSValue thenResult = JS_Call(ctx, thenMethod, promise, 2, (JSValueConst[]){resolvedFunc, rejectedFunc});
// 调用catch方法:promise.catch(onRejected)
JSValue catchResult = JS_Call(ctx, catchMethod, promise, 1, (JSValueConst[]){rejectedFunc});

// 释放临时对象
JS_FreeValue(ctx, resolvedFunc);
JS_FreeValue(ctx, rejectedFunc);
JS_FreeValue(ctx, thenResult);
JS_FreeValue(ctx, catchResult);
JS_FreeValue(ctx, thenMethod);
JS_FreeValue(ctx, catchMethod);

完整示例

把所有步骤整合起来,完整的可运行代码示例如下:

#include "quickjs.h"
#include <stdio.h>

JSValue onResolved(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
    if (argc > 0) {
        const char *val = JS_ToCString(ctx, argv[0]);
        printf("Promise resolved: %s\n", val);
        JS_FreeCString(ctx, val);
    }
    return JS_UNDEFINED;
}

JSValue onRejected(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
    if (argc > 0) {
        const char *reason = JS_ToCString(ctx, argv[0]);
        printf("Promise rejected: %s\n", reason);
        JS_FreeCString(ctx, reason);
    }
    return JS_UNDEFINED;
}

int main() {
    JSRuntime *rt = JS_NewRuntime();
    JSContext *ctx = JS_NewContext(rt);

    // 创建PromiseCapability
    JSValue resolvingFuncs[2];
    JSValue promise = JS_NewPromiseCapability(ctx, resolvingFuncs);
    JSValue resolveFunc = resolvingFuncs[0];
    JSValue rejectFunc = resolvingFuncs[1];

    // 获取Promise原型的then和catch方法
    JSValue promiseConstructor = JS_GetPropertyStr(ctx, JS_GetGlobalObject(ctx), "Promise");
    JSValue promisePrototype = JS_GetPropertyStr(ctx, promiseConstructor, "prototype");
    JSValue thenMethod = JS_GetPropertyStr(ctx, promisePrototype, "then");
    JSValue catchMethod = JS_GetPropertyStr(ctx, promisePrototype, "catch");
    JS_FreeValue(ctx, promiseConstructor);
    JS_FreeValue(ctx, promisePrototype);

    // 创建回调函数
    JSValue resolvedFunc = JS_NewCFunction(ctx, onResolved, "onResolved", 1);
    JSValue rejectedFunc = JS_NewCFunction(ctx, onRejected, "onRejected", 1);

    // 绑定then和catch
    JS_Call(ctx, thenMethod, promise, 2, (JSValueConst[]){resolvedFunc, rejectedFunc});
    JS_Call(ctx, catchMethod, promise, 1, (JSValueConst[]){rejectedFunc});

    // 测试resolve(注释掉下面一行,打开reject测试即可验证拒绝逻辑)
    JS_Call(ctx, resolveFunc, JS_UNDEFINED, 1, (JSValueConst[]){JS_NewString(ctx, "Success!")});
    // JS_Call(ctx, rejectFunc, JS_UNDEFINED, 1, (JSValueConst[]){JS_NewString(ctx, "Error occurred!")});

    // 执行事件循环,处理Promise异步回调
    JS_ExecutePendingJob(rt, NULL);

    // 释放所有资源
    JS_FreeValue(ctx, resolvedFunc);
    JS_FreeValue(ctx, rejectedFunc);
    JS_FreeValue(ctx, thenMethod);
    JS_FreeValue(ctx, catchMethod);
    JS_FreeValue(ctx, resolveFunc);
    JS_FreeValue(ctx, rejectFunc);
    JS_FreeValue(ctx, promise);
    JS_FreeContext(ctx);
    JS_FreeRuntime(rt);

    return 0;
}

注意:QuickJS中的Promise回调是异步执行的,必须调用JS_ExecutePendingJob来处理待执行的异步任务,否则回调不会被触发。

内容的提问来源于stack exchange,提问作者Anurag Vohra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 17:01:08