关于 ES6 中的 Promise 链

About Promise chain in ES6

我对 ES6 中的 Promise 链感到困惑。

function taskA() {
  console.log("Task A");
  throw new Error("throw Error @ Task A")
}

function taskB() {
  console.log("Task B");
}

function onRejected(error) {
  console.log(error);// => "throw Error @ Task A" 
}
  
function finalTask() { 
  console.log("Final Task");
}

var promise = Promise.resolve(); 
promise
.then(taskA) 
.then(taskB) 
.catch(onRejected) 
.then(finalTask);

我在这里迷路的是为什么 finalTask 会被调用? catch() 是否链 returns 已解决的 Promise?

当您提供 .catch() 处理程序或 .then() 的第二个参数时,被拒绝的承诺是 "handled"。默认情况下,当您提供这样的拒绝处理程序时,承诺系统将假定拒绝已被处理并且链应该继续。

如果您不希望链继续,则可以从拒绝处理程序中 return 拒绝承诺或抛出错误。然后这将停止该链直到链中的另一个拒绝处理程序。

所以,这里是像你展示的链中的可能性:

1) 链中没有拒绝处理程序

链完全停止,不再执行 .then() 履行处理程序。

2) 链中有一个拒绝处理程序,它要么 return 什么都没有,要么 return 是一个常规值或一个已履行的承诺或一个最终会履行的承诺。

这是您的代码当前显示的内容。拒绝被视为已处理,链的承诺状态变为已履行的承诺,因此调用链中的后续履行处理程序。

3) 链中有一个拒绝处理程序 return 是一个被拒绝的承诺或抛出一个错误

返回被拒绝的承诺(或将来拒绝的承诺)或抛出新错误(变成被拒绝的承诺)将停止链的进一步处理,直到下一个错误处理程序。

因此,如果您将 onRejected() 处理程序更改为:

function onRejected(error) {
     console.log(error);
     throw error;    // rethrow error to stop the rest of the chain
}

那么,你的承诺链就到此为止了。


了解它为何以这种方式工作很重要。这允许您处理 promise 链中间的错误,并且处理错误的代码可以根据 return 或抛出的内容来决定链是否继续。如果它 return 什么都没有或正常值或已履行的承诺,则链的处理将继续 - 错误已得到处理 - 无需停止进一步处理。

但是,如果错误比这更严重并且处理不应继续,那么拒绝处理程序可以抛出相同的错误或抛出不同的错误或 return 拒绝承诺并且链将跳过链中下一个拒绝处理程序之前的所有执行处理程序。