JavaScript Promise.all()


今天我們學習使用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

當所有的promiseresolve時,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(),明天見。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM