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

如何在自定义JS Promise类中实现catch错误捕获方法

实现简易Promise的catch方法步骤

你当前的代码问题在于只用了一个cb同时处理成功和失败回调,而Promise需要区分成功(resolve)和失败(reject)的回调逻辑。以下是实现catch方法的具体步骤:


1. 拆分成功与失败回调变量

首先在MyPromise的构造函数里,把原来单一的cb拆成两个独立的回调存储变量,分别对应成功和失败场景:

class MyPromise {
    constructor(initFunction) {
        // 替换原来的this.cb,分别存储成功、失败回调
        this.onResolve = () => {};
        this.onReject = () => {};
        initFunction(this.#resolve.bind(this), this.#reject.bind(this));
    }

    #resolve(value) {
        // 调用成功回调
        this.onResolve(value);
    }

    #reject(value) {
        // 调用失败回调
        this.onReject(value);
    }

    then(cb) {
        this.onResolve = cb;
        return this; // 支持链式调用
    }
}

2. 实现catch方法

直接给MyPromise添加catch方法,它的作用就是接收失败回调并赋值给this.onReject,同样返回实例以支持链式调用:

catch(cb) {
    this.onReject = cb;
    return this;
}

3. 补充状态管理(解决异步回调延迟绑定问题)

现在还有个潜在问题:如果Promise已经完成(resolve/reject),之后再调用then或catch,回调不会触发。比如同步执行resolve的场景,或者像你的add函数里,1秒后执行reject,但如果catch是在1秒之后才绑定的,就不会生效。所以需要给Promise添加状态管理:

修改构造函数和私有方法:

class MyPromise {
    constructor(initFunction) {
        this.status = 'pending'; // 初始状态:pending/fulfilled/rejected
        this.result = undefined; // 存储resolve的值或reject的错误
        this.onResolve = () => {};
        this.onReject = () => {};

        try {
            // 捕获初始化函数里抛出的同步错误
            initFunction(this.#resolve.bind(this), this.#reject.bind(this));
        } catch (err) {
            this.#reject(err);
        }
    }

    #resolve(value) {
        // 只有pending状态才能变更状态
        if (this.status === 'pending') {
            this.status = 'fulfilled';
            this.result = value;
            this.onResolve(value);
        }
    }

    #reject(value) {
        if (this.status === 'pending') {
            this.status = 'rejected';
            this.result = value;
            this.onReject(value);
        }
    }

    then(cb) {
        // 如果已经是成功状态,立即执行回调
        if (this.status === 'fulfilled') {
            cb(this.result);
        } else if (this.status === 'pending') {
            this.onResolve = cb;
        }
        return this;
    }

    catch(cb) {
        // 如果已经是失败状态,立即执行回调
        if (this.status === 'rejected') {
            cb(this.result);
        } else if (this.status === 'pending') {
            this.onReject = cb;
        }
        return this;
    }
}

4. 测试验证

现在你的add函数可以正常使用catch了:

add(2, '5').then(result => console.log(result)).catch(error => console.log(error));
// 1秒后输出:Invalid params

内容的提问来源于stack exchange,提问作者daniel sas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 12:18:25