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

多次调用含Promise的show函数后仅首次触发resolve方法的原因

问题:为何Promise的resolve回调仅首次执行?

代码示例

var i = 1;
var x;
var z = 1
setTimeout(show, 8000);
setTimeout(show, 4000);
show();

function show() {
    console.log("Hello,show was called:- ", z);                    //to check if control is going inside show() function
    z++;

    x = new Promise(function (resolve, reject) {
        setTimeout(function () {
            if (i >= 1)
                resolve();
            else
                reject();

        }, 1000);
    });
}

x
    .then(
        () => {
            console.log("Resolve was called:- ", i);
            i++;

        }
    )
    .catch(
        () => {
            console.log("Wrong limit");
        }
    )

运行输出

Hello,show was called:-  1
Resolve was called:-  1
Hello,show was called:-  2
Hello,show was called:-  3

原因分析

核心问题在于变量x被重复赋值,且只有第一次赋值的Promise绑定了.then/.catch回调:

  • 首次调用show()时,x被赋值为第一个Promise对象,后续代码中的x.then(...)为这个Promise注册了resolve回调。1秒后该Promise resolve,触发回调输出日志。
  • 4秒后第二次调用show(),x被覆盖为一个全新的Promise,但这个新Promise没有绑定任何.then/.catch回调。即使1秒后它成功resolve,也没有对应的回调函数可以执行。
  • 8秒后第三次调用show()同理,x再次被替换为新的Promise,同样未注册回调,因此不会输出resolve相关日志。

修复方案

如果希望每次调用show()时,内部创建的Promise都能触发回调,有两种常见方式:

  1. 在show()函数内部,为当前创建的Promise直接绑定回调:
function show() {
    console.log("Hello,show was called:- ", z);
    z++;

    // 直接为当前Promise绑定回调
    new Promise(function (resolve, reject) {
        setTimeout(function () {
            if (i >= 1)
                resolve();
            else
                reject();
        }, 1000);
    })
    .then(() => {
        console.log("Resolve was called:- ", i);
        i++;
    })
    .catch(() => {
        console.log("Wrong limit");
    });
}
  1. 避免覆盖x,而是每次将新Promise存入数组,统一处理(如果需要批量操作):
var i = 1;
var promises = []; // 用数组存储所有Promise
var z = 1
setTimeout(show, 8000);
setTimeout(show, 4000);
show();

function show() {
    console.log("Hello,show was called:- ", z);
    z++;

    const p = new Promise(function (resolve, reject) {
        setTimeout(function () {
            if (i >= 1)
                resolve();
            else
                reject();
        }, 1000);
    });
    promises.push(p); // 存入数组
}

// 遍历数组为每个Promise绑定回调
promises.forEach(p => {
    p.then(() => {
        console.log("Resolve was called:- ", i);
        i++;
    })
    .catch(() => {
        console.log("Wrong limit");
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 18:20:42