2016-11-04 206 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; } 
);