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

JavaScript手写Promise链式调用出现Cannot read property 'then' of undefined错误原因

问题原因分析

报错的直接原因是then方法没有返回新创建的MyPromise实例:你在then方法内部创建了用于链式传递的promise对象,但方法执行结束没有把这个实例返回,导致第一次调用then后返回值为undefined,再链式调用.then()自然会抛出Cannot read property 'then' of undefined的错误。

除此之外你的自定义Promise还存在多处逻辑缺陷,修复后才能正常运行:

  • 构造函数的异常捕获逻辑错误:catch块中只对onReject做了绑定没有执行,也没有传入捕获到的异常参数
  • 实例类型判断逻辑错误:用typeof result === 'MyPromise'判断实例是无效的,typeof判断对象只会返回object,应该用instanceof关键字
  • 拒绝状态取值错误:propageRejected方法中调用catch函数时传入的是this.value,应该传入存储拒绝原因的this.error
  • 缺省回调的透传逻辑缺失:如果then方法没有传入对应状态的回调函数,需要把值/错误直接透传给下一个Promise实例
核心代码修复示例

修复then方法的返回逻辑

then = (fullfilledFn, catchFn) => {
    const promise = new MyPromise();
    this.thenQueue.push([promise, fullfilledFn, catchFn]);
    if(this.state === states.FULFILLED) {
        this.propageFulFilled()
    } else if(this.state == states.REJECTED) {
        this.propageRejected();
    }
    // 新增返回promise实例,支持链式调用
    return promise;
}

修复构造函数的异常捕获逻辑

setTimeout(() => {
    try {
        computation(
            this.onFulFilled.bind(this),
            this.onReject.bind(this)
        );
    } catch(ex) {
        // 直接执行onReject传入异常
        this.onReject(ex);
    }
});

修复完成状态的传播逻辑

propageFulFilled = () => {
    for(const [promise, fullFilledFn] of this.thenQueue) {
        // 缺省回调直接透传值
        if (typeof fullFilledFn !== 'function') {
            promise.onFulFilled(this.value);
            continue;
        }
        const result = fullFilledFn(this.value);
        // 改用instanceof判断实例类型
        if(result instanceof MyPromise) {
            result.then(
                value => promise.onFulFilled(value),
                error => promise.onReject(error)
            )
        } else {
            promise.onFulFilled(result);
        }
    }
    this.thenQueue = [];
}

修复拒绝状态的传播逻辑

propageRejected = () => {
    for(const [promise, _, catchFn] of this.thenQueue) {
        // 缺省错误回调直接透传错误
        if (typeof catchFn !== 'function') {
            promise.onReject(this.error);
            continue;
        }
        const result = catchFn(this.error);
        if(result instanceof MyPromise) {
            result.then(
                value => promise.onFulFilled(value),
                error => promise.onReject(error)
            )
        } else {
            promise.onFulFilled(result);
        }
    }
    this.thenQueue = [];
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 00:39:04