先看下Promise.all的具體用法web
const p = Promise.all([p1, p2, p3]).then(() => { // 當 p一、p二、p3 都是relsolved狀態時,調用此回調方法 }).catch(() => { // 當有一個是rejected時,就調用此回調方法 })
當p1的狀態爲rejected時,p二、p3都不會再執行,很顯然這是一個大缺陷,可是,若是做爲參數的 Promise 實例(p一、p二、p3),本身定義了catch方法,那麼它一旦被rejected,並不會觸發Promise.all()的catch方法。promise
const p1 = new Promise((resolve, reject) => { throw new Error('報錯了'); }) .then(result => result) .catch(e => e); const p2 = new Promise((resolve, reject) => { resolve('hello'); }) .then(result => result) .catch(e => e); Promise.all([p1, p2]) .then(result => console.log(result)) .catch(e => console.log(e)); // // [Error: 報錯了, "hello",]
p1有本身的catch方法,該方法返回的是一個新的 Promise 實例,p1指向的其實是這個實例。該實例執行完catch方法後,也會變成resolved,致使Promise.all()方法參數裏面的兩個實例都會resolved,所以會調用then方法指定的回調函數,而不會調用catch方法指定的回調函數。
因此,爲了解決上面提到的缺陷,能夠用如下的寫法:svg
Promise.all([p1, p2, p3].map(promise => promise.catch(err => err)).then(() => {})