2014-09-12 115 views
29

有人提出了一個有趣的案例今天與藍鳥,處理多個承諾的最佳方式,我們不想停止給定履行或拒絕,而是寧願有興趣檢查最終結果。舉例:Bluebird Promise.all - 多個承諾完成彙總成功和拒絕

var p1 = new Promise(function(f,r){ 
    setTimeout(function(){ 
     console.log("p1"); 
     f("yay"); 
    }, 100); 

}); 

var p2 = new Promise(function(f,r){ 
    setTimeout(function(){ 
     console.log("p2"); 
     r(new Error("boo")); 
    }, 200); 

}) 

var p3 = new Promise(function(f,r){ 
    setTimeout(function(){ 
     console.log("p3"); 
     r(new Error("yay")); 
    }, 300); 

}); 

var p4 = new Promise(function(f,r){ 
    setTimeout(function(){ 
     console.log("p4"); 
     f("yay"); 
    }, 400); 

}); 


//Promise.all([p1,p2, p3, p4]).then(function(p){ 
// console.log("Results:",p); 
//}).error(function(e){ 
// console.log("Error:",e); 
//}); 

Promise.map([p1,p2, p3, p4],function(p){ 
    console.log("results:",p); 
}, {concurrency:10}).error(function(e){ 
    console.log("Error:",e); 
}); 

在這裏,如果我們運行map或所有被拒絕的promise都會導致處理程序不報告結果。

例如運行Promise.map如上實現的結果是:

debugger listening on port 65222 
p1 
results: yay 
p2 
Error: [Error: boo] 
p3 
p4 

Process finished with exit code 0 

在這裏爲每個承諾的代碼執行,但只有1個結果和1個錯誤被報告。該錯誤導致該進程停止。

如果我們取消註釋,我們會得到類似的行爲。這次只報告錯誤。任何成功都沒有成功(可以理解)。

debugger listening on port 65313 
p1 
p2 
Error: [Error: boo] 
p3 
p4 

Process finished with exit code 0 

鑑於這種行爲什麼會着手實現由地方經營的是所有的承諾和履行承諾的結果報告與任何及所有拒絕情景的最佳方式?

喜歡的東西:

Promise.aggregate([p1,p2,p3,p4]).then(function(fulfilled, rejected){ 
    console.log(fulfilled); //all success 
    console.log(rejected); //any and all rejections/exceptions 
}); 

回答

34

你會使用.reflect

Promise.all([p1,p2,p3,p4].map(x => x.reflect()).then(results => { 
    results.forEach(result => { 
    if(result.isFulfilled()){ 
     // access result.value() 
    } else { 
     // access result.reason() 
    } 
    }); 
}); 

這用於與settle功能,傳統上就是這樣做的一個數組來處理 - 它是由.reflect因爲廣義它將聚合與承諾檢查的概念分開,並讓您執行​​所做的操作,但也可以執行其他操作,如.any.some

+1

我不認爲.settle被藍鳥支持了,在他們的文檔中沒有提及它。 – silverlight513 2016-03-09 11:02:27

+2

@ silverlight513對不起,我們不推薦定居 - 它仍然可以工作。前進的方向是使用'.reflect'。感謝您提醒我注意我會更新答案。 – 2016-03-09 11:09:19

+0

感謝您的更新 – j03m 2016-06-20 13:44:00