将拒绝()跳过Promise中的所有跟随()

时间:2017-03-03 16:11:34

标签: javascript promise

我一直很好奇,如果承诺在任何位置遭到拒绝,以下then()仍会被执行吗?以下面的代码为例:

Promise.reject('reJECTed')
.then(() => {
    console.log('before resolve()');
    return Promise.resolve('reSOLVed');
})
.then((msg) => {
    console.log('reSOLVed inside 1st then()');
    console.log(msg);
}, (msg) => {
    console.log('reJECTed inside 1st then()');
    console.log(msg);
})
.then((msg) => {
    console.log('reSOLVing inside 2nd then()');
    console.log(msg);
}, (msg) => {
    console.log('reJECTing inside 2nd then()');
    console.log(msg);
})
.catch((msg) => {
    console.log('reJECTed in catch()');
    console.log(msg);
});

会打印

reJECTed inside 1st then()
reJECTed
reSOLVing inside 2nd then()
undefined
控制台上的

,表示第二个resolve()中的then()和最后一个catch()未执行。这是否意味着在遇到reject()后,resolve()内的任何then()内的任何table{ background: white; width: 85%; margin: 60px auto; border-spacing: 0; } th{ border-bottom: 2px yellow solid; height: 30px; font-size: 12px; display: table-cell; vertical-align: bottom; padding-bottom: 2px; }完全被跳过,直到被捕获为止?

感谢您的解释!

3 个答案:

答案 0 :(得分:5)

  

这是否意味着当遇到reject()时,then()中的任何后续resolve()被完全跳过,直到被捕获为止?

是。当promise拒绝时,链中的所有解析处理程序都会被跳过,直到某个拒绝处理程序处理拒绝并将promise链更改回来实现。

而且,如果你没有意识到,.then()处理程序的第二个参数是拒绝处理程序(与.catch()处理程序几乎相同)。

但是,请记住,如果你有一个拒绝处理程序并且它没有throw或者返回一个被拒绝的承诺,那么这个链就会再次被满足,因为你已经处理了#34;拒绝。它与try/catch完全一样。如果您catch并且没有重新抛出,则会处理异常并在此之后继续正常执行。

因此,在输出reJECTed inside 1st then()的拒绝处理程序中,您没有返回任何内容,因此在此时,承诺链将得到满足。拒绝已被处理"在那一点上,承诺链现在切换到履行状态。

这里有一些关于代码的注释:

Promise.reject('reJECTed')
.then(() => {
    // this fulfilled handler is skipped because the promise chain is rejected here
    console.log('before resolve()');
    return Promise.resolve('reSOLVed');
})
.then((msg) => {
    // this fulfilled handler is skipped because the promise chain is rejected here
    console.log('reSOLVed inside 1st then()');
    console.log(msg);
}, (msg) => {
    // this reject handler is called because the promise chain is rejected here
    console.log('reJECTed inside 1st then()');
    console.log(msg);
    // because this does not rethrow or return a rejected promise
    // the promise chain switches to fulfilled
})
.then((msg) => {
    // this fulfilled handler is called because the promise chain is fulfilled now
    console.log('reSOLVing inside 2nd then()');
    console.log(msg);
}, (msg) => {
    // this reject handler is not called because the promise chain is fulfilled now
    console.log('reJECTing inside 2nd then()');
    console.log(msg);
})
.catch((msg) => {
    // this reject handler is not called because the promise chain is fulfilled now
    console.log('reJECTed in catch()');
    console.log(msg);
});

让我举一个例子来说明一个承诺链如何切换状态:



Promise.reject("Hello").then(val => {
    console.log("1: I am not called");
}).catch(err => {
    console.log("2: I am rejected");
    // rethrow to keep promise chain rejected
    throw err;
}).catch(err => {
    console.log("3: I am still rejected");
    // return normal value, promise chain switches to fulfilled
    return "GoodBye";
}).then(val => {
    console.log("4: Now back to fulfilled state");
}).catch(err => {
    console.log("5: Not called");
});




答案 1 :(得分:1)

是的,场景B

中对此进行了描述

Promise.reject会导致拒绝承诺,这意味着

情景A

导致未处理的承诺,如果没有,则捕获

情景B

它将回退到catch

指定的第一个then或错误挂钩

Promise.reject()
      .then(
       () => {},
       () => { console.log ('Im called') } // goes here
      )

    Promise.reject()
      .catch(() => { console.log('Im called as well') }) // or here

请记住,thencatch会返回

  • 解决了返回值的承诺
  • 或抛出错误/拒绝承诺

现在一切都从场景A或B再次进行,例如

Promise.reject()
      .catch(() => { return 5; }) // returns promise that resolves to 5, 
      .then(
        res => console.log('See, Im not rejected and resolve to', 5),
        () => {}
      );

答案 2 :(得分:0)

Promise.then()方法提供了两个回调参数。第一个是resolved时调用的,第二个是rejected时调用的。所以上面的代码叫做Promise.then(resolved,rejected),有两个回调形式;