今天我們學習使用Promise.all()
這個靜態方法來聚合多個異步任務的結果。
Promise.all()
函數接受一個具有多個promise
的數組作為參數,並返回一個promise對象。
什么時候返回?
- 當數組中的所有Promise全部被
resolve
或者reject
Promise.all的語法:
Promise.all([promise1, promise2, promise3]) .then(console.log) .catch(console.log)
首先傳入一個數組,數組中的每個值為promise對象。
如果數組中的每個promise都被resolve,則Promise.all會返回一個新的promise對象,並reslove一個數組,里面是每個promise返回的值,同樣按照傳入的順序。
如果數組中的某個promise被reject,Promise.all也會返回新的promise對象,reject第一個失敗的promise所返回的值,如果后面的promise也有失敗也不會返回。
當我們處理同時多個異步請求的時候,Promise.all非常的有用。
Promise.all() 示例代碼
看明白代碼就會了
成功resolve Promise示例
下面的3個promise分別在第1、2、3秒的時候成功返回數字10、20、30。我們用setTimeout來模擬異步操作。
我需要將這個3個promise所返回的結果進行計算總和。
如果使用昨天的鏈式調用的話,結果將在1+2+3,6秒后才能返回結果。
但今天我們使用Promise.all,同時處理3個異步操作,最長時間的是p3的promise,所以3秒后就可以計算出結果。
const p1 = new Promise((resolve, reject) => { setTimeout(() => { console.log('第一個promise被resolve'); resolve(10); }, 1 * 1000); }); const p2 = new Promise((resolve, reject) => { setTimeout(() => { console.log('第二個promise被resolve'); resolve(20); }, 2 * 1000); }); const p3 = new Promise((resolve, reject) => { setTimeout(() => { console.log('第三個promise被resolve'); resolve(30); }, 3 * 1000); }); Promise.all([p1, p2, p3]) .then(results => { const total = results.reduce((p, c) => p + c); console.log(`返回結果: ${results}`); console.log(`計算總數: ${total}`); }); // 輸出: // 第一個promise被resolve // 第二個promise被resolve // 第三個promise被resolve // 返回結果: 10,20,30 // 計算總數: 60
當所有的promise被resolve時,Promise.all
的 then 會被調用,results 為p1,p2,p3
結果組成的數組。
最后使用reduce方法求10+20+30
的結果。
失敗reject Promise示例
有成功就會有失敗,下面來看看如果有失敗的異步操作怎么辦
const p1 = new Promise((resolve, reject) => { setTimeout(() => { console.log('第一個promise被resolve'); resolve(10); }, 1 * 1000); }); const p2 = new Promise((resolve, reject) => { setTimeout(() => { console.log('第二個promise被reject'); reject('失敗'); }, 2 * 1000); }); const p3 = new Promise((resolve, reject) => { setTimeout(() => { console.log('第三個promise被resolve'); resolve(30); }, 3 * 1000); }); Promise.all([p1, p2, p3]) .then(console.log) .catch(console.log); // 輸出: // 第一個promise被resolve // 第二個promise被reject // 失敗 // 第三個promise被resolve
這個例子中,p1在1秒后成功返回,p2在2秒后失敗,p3在3秒后成功返回。
再看Promise.all
,catch方法執行並打印出p2的reject返回值,因為promise中有失敗,所以then方法並不會執行。
如果p3也失敗呢?
const p1 = new Promise((resolve, reject) => { setTimeout(() => { console.log('第一個promise被resolve'); resolve(10); }, 1 * 1000); }); const p2 = new Promise((resolve, reject) => { setTimeout(() => { console.log('第二個promise被reject'); reject('p2失敗'); }, 2 * 1000); }); const p3 = new Promise((resolve, reject) => { setTimeout(() => { console.log('第三個promise被reject'); reject('p3失敗'); }, 3 * 1000); }); Promise.all([p1, p2, p3]) .then(console.log) .catch(console.log); // 輸出: // 第一個promise被resolve // 第二個promise被reject // p2失敗 // 第三個promise被reject
可以看到結果還是相同,catch只打印了p2錯誤的值,並沒有返回p3的reject的值,說明Promise.all的只會reject第一個失敗的值,后面的失敗返回並不會傳入到catch中。
這在平時的使用中要注意,如果想要拿到所有的失敗返回值,用reject是做不到。
好,今天的Promise.all學習筆記到這,明天講講Promise.race(),明天見。