2015-09-27 31 views
5

我对ES6中的Promise链感到困惑。关于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()链是否返回已解决的Promise?

+0

[Chained promises not passing on rejection](http://stackoverflow.com/q/16371129/1048572) – Bergi

回答

13

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

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

所以,这里是像你这样的链的可能性表示:

1)是链

没有拒绝处理程序链完全停止,没有进一步.then()履行处理程序执行。

2)链中有一个拒绝处理程序,它不会返回任何内容或返回正常值或已履行的承诺或最终实现的承诺。

这是您的代码当前显示的内容。拒绝被认为是被处理的,并且链的承诺状态改变为履行的承诺,以便链中的后续履行处理程序被调用。

3)有一个在其任一返回一个拒绝承诺或引发错误

返回被拒绝的承诺(或在未来将拒绝一个承诺)或投掷新的误差(链中的拒绝处理程序这将变成被拒绝的承诺)将停止进一步处理链直到下一个错误处理程序。

所以,如果你改变了你onRejected()处理程序是:

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

然后,你的诺言链会停在那里。


重要的是要理解它为什么这样工作。这允许您在promise链的中间处理错误,并且处理错误的代码可以根据返回或抛出的内容来决定链是否继续。如果它不返回任何内容或正常值或履行的承诺,则链的处理继续 - 错误已处理 - 不需要停止进一步处理。

但是,如果错误比这更严重并且处理不应继续,则拒绝处理程序可以抛出相同的错误或抛出不同的错误或返回被拒绝的承诺,并且链将跳过任何履行处理程序直到链中的下一个拒绝处理程序。

+1

非常感谢!你的解释很清楚。 – JasmineOT

+2

这种方式与同步try {} catch(e){}'中的catch类似(类似的情况是除非重新进行处理才会处理错误)。 – jib