2016-11-28 111 views
4

鑑於以下是否有可能在Promise.all中捕獲所有被拒絕的承諾?

Promise.all(promises).then(resolved => { 
    ... 
}).catch(rejected => { 
    ... 
}); 

rejected將僅包含第一個承諾被拒絕。有沒有辦法趕上全部被拒絕的承諾?

+1

單獨,是,但不是.all。正如你所發現的那樣,第一個被拒絕的承諾會引發爭議;它並不等待他們完成。你將不得不循環每個承諾並附加捕獲處理程序,然後以某種方式確定它們何時全部完成(因爲在那一點上將是無用的) –

+0

'rejected'將不包含第一個被拒絕的承諾 - 它將包含**原因**被拒絕。 – 2016-11-28 19:07:47

+1

另請參閱[這個問題](http://stackoverflow.com/questions/37902927/resolve-and-reject-all-promises-in-bluebird)如何處理這種情況與藍鳥。檢查使事情變得更容易。 – estus

回答

10

當然,這樣做需要等待,直到所有輸入的承諾已經解決。只要有人正在等待,可能會拒絕,你不能確定你有所有的拒絕!

所以,你可以使用Promise.all,而是將輸入後承諾,以趕上拒絕和識別它們,也許在Error對象包裝它們,如

caughtPromises = promises.map(promise => promise.catch(Error)); 

Promise.all結果現在篩選出找到標識爲失敗的人:

Promise.all(caughtPromises) 
    .then(results => results.filter(result => result instanceof Error)) 

etvoilà。

0

等待所有承諾解決(解決或拒絕)的常用方法是使用類似Promise.settle()之類的東西。你可以在這裏看到它的幾種不同的變化:ES6 Promise.all() error handle - Is .settle() needed?

基本的概念是,你用一個包裝器來包裝你的每一個承諾,它捕獲(並保存)它們的拒絕,並將它們變成解決方案,然後你將這些承諾傳遞給Promise.all()。由於您傳遞給Promise.all()的所有承諾都將解決(不會拒絕),因此它將等待所有這些承諾。但是,然後將得到的值將是一個數組,你可以遍歷,看看它承諾解決,駁回:

你將他們使用這樣的:

Promise.settle(arrayOfPromises).then(function(results) { 
    results.forEach(function(pi, index) { 
     if (pi.isFulfilled()) { 
      console.log("p[" + index + "] is fulfilled with value = ", pi.value()); 
     } else { 
      console.log("p[" + index + "] is rejected with reason = ", pi.reason()); 
     } 
    }); 
}); 

請參閱上面的鏈接發佈Promise.settle()的實際代碼以避免在此重複。

相關問題