解決Promise.all一個被rejected,整個都被rejected的缺陷

先看下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(() => {})