2016-11-04 208 views
2

在与Promises玩弄了解他们如何工作时,我注意到了一些我无法解释的东西。Promise.all - 解决回调火灾,虽然承诺被拒绝

考虑这个例子:

var A = function() { 
    return Promise.resolve(); 
}; 

var B = function() { 
    return Promise.reject(); 
}; 

var c = A(); 
var d = B(); 

c.then(
    function() { console.log('A success'); }, 
    function() { console.log('A fail'); } 
); 

d.then(
    function() { console.log('B success'); }, 
    function() { console.log('B fail'); } 
); 

Promise.all([c, d]).then(
    function() { console.log('all success'); }, 
    function() { console.log('all fail'); } 
); 

第一单的决心/拒绝回调火,其次是Promise.all拒绝回调。这是预期的,因为B拒绝承诺。

但是,当这样写的,中Promise.all火灾决心回调:

var A = function() { 
    return Promise.resolve(); 
}; 

var B = function() { 
    return Promise.reject(); 
}; 

var c = A().then(
    function() { console.log('A success'); }, 
    function() { console.log('A fail'); } 
); 
var d = B().then(
    function() { console.log('B success'); }, 
    function() { console.log('B fail'); } 
); 

Promise.all([c, d]).then(
    function() { console.log('all success'); }, 
    function() { console.log('all fail'); } 
); 

,因为这两个承诺之一被拒绝,所以无极返回由all也应该被拒绝这是出乎意料的。

这里发生了什么 - 确实与返回值有关吗?我需要在某处返回一个新的承诺吗?

+0

完全预期的行为,因为你的处理exeption ..不要处理你的期望,然后你的一切都会抓住他们。或者在拒绝处理程序中返回拒绝。 – Keith

+0

你并没有等待'B',你正在等待'B'的'then'返回的承诺。 – mrmcgreg

+0

在第一个函数中,您已经在第一个'then'调用中发现了错误,并且之后的promise链会自动重置,因为错误已被处理。 – adeneo

回答

0

你的两个例子看起来很相似,但并不完全相同。这里是documentationthen(重点煤矿):

呼叫onFulfilledonRejected与履约价值或承诺的拒绝理由(如适用),并返回一个新的承诺解析为的所谓的返回值处理程序。

在您的第一个示例中,d设置为B()的结果,这是拒绝承诺。新的承诺意味着记录了某些内容,但d未更改。

在第二个示例中,d更改为B().then(...)的结果,这是一个已解决的承诺。

您可能想在拒绝处理程序中使用throw

0

你抑制误差在第二种情况:

// d is promise which suppressed error from B() 
var d = B().then(
    function() { console.log('B success'); }, 
    function() { console.log('B fail'); } 
); 

你应该,如果你想再次抛出错误d被拒绝,以及:

var d = B().then(
    function() { console.log('B success'); }, 
    function (e) { console.log('B fail'); throw e; } 
);