关于promise动态传入then参数的问题

我写了如下三个函数

//A函数 延迟3秒执行
const getA=()=>new Promise(resolve=>{
    setTimeout(()=>{
        console.log('A');
        resolve({msg:'A'});        
    },3000);
});
//B函数 调用reject方法
const getB=()=>new Promise((resolve,reject)=>{
    console.log('B');
    reject({msg:'B'});    
});
//C函数 使用resolve
const getC=()=>new Promise((resolve,reject)=>{
    console.log('C');
    resolve({msg:'C'});
});

然后我使用动态传入then参数的方法执行:

let promise=Promise.resolve();


for(let func of [getA,getB,getC]){
    promise=promise.then(()=>{
        console.log('执行了函数'+func.name);
        return func();
    });
}

promise.catch(e=>{
    console.log(e);
});

最后结果:
image.png

这样就有一个问题:为什么在for循环的过程中C函数没有直接被执行?
这样看起来貌似是js预编译了这一段代码,使得B函数reject之后,被catch捕获从而中断了C函数的执行。
但是按照js的逻辑,不是应该从上到下顺序执行吗?
又或者说这与js的宏任务和微任务有关?

阅读 645
评论 2月16日提问
    4 个回答

    原因是then的两个参数fulfilled和rejected,你的代码中B reject了,而后续的then只添加了fulfilled函数没有rejected函数,因此C不会被执行。并且B的rejected会持续传到到最后的catch

    评论 赞赏
      fefe
      • 8.2k

      只有 Promise 变成 fullfilled 才会执行 then 的第一个回调。

      rejected Promise 不会执行 then 的第一个回调。

      Promise.prototype.then 可以接受两个参数,都是回调,第一个 fullfilled 之后执行,第二个 rejected 之后执行。两个只会执行一个。

      评论 赞赏
        happyy
        • 165

        Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)

        因为你没有写catch捕获reject

        所以你这么写就有输出了

        for(let func of [getA,getB,getC]){
         promise=promise.then(()=>{
             console.log('执行了函数'+func.name);
             return func();
         }).catch(e=>{
           console.log(e);
         });;
        }

        out:

        执行了函数getA
        A
        执行了函数getB
        B
        { msg: 'B' }
        执行了函数getC
        C
        评论 赞赏

          这跟 Promise 关系不大,你只是单纯不理解函数什么时候会被执行而已。

          建议:好好理解一下 函数声明函数执行 之间的关系,再按照语法推演一下你的代码。

          评论 赞赏
            撰写回答

            登录后参与交流、获取后续更新提醒