搞清楚Promise.all的異常處理

參考資料:
https://www.jianshu.com/p/356f10ee476d
https://blog.csdn.net/aaqingying/article/details/122966849
https://www.cnblogs.com/hill-foryou/p/12512885.html

背景:
很多情況下,一個頁面需要異步請求多個接口,這個時候可以使用Promise.all並且發送請求。但是,Promise.all中的任何一個promise出現錯誤的時候都會執行catch,導致其他正常返回的數據無法使用。

Promise.all基本特性

  • 接收一個 Promise 數組,執行結果返回一個新的 Promise
  • 所有 Promise 都成功的時候,返回的 Promise 纔是成功
  • 要是有一個 Promise 失敗,則返回的 Promise 是失敗

Promise.all的基本使用

舉個例子:

var p1 = Promise.resolve(1);
var p2 = Promise.resolve(2);
var p3 = new Promise((resolve, reject) => {
    setTimeout(resolve, 100, "3");
});

var p4 = Promise.reject(4);
var p5 = Promise.reject(5).catch((e) => e);

// 情況1:promise全部resolve
Promise.all([p1, p2, p3]).then(values => {
    console.log(values); // 其中p1、p2、p3都成功,所以進入then()
}).catch(function(err) {
    console.log(err); // 永遠走不到這裏
});

// 情況2:promise有一個reject,且reject沒有主動捕獲異常
Promise.all([p1, p2, p4]).then(values => {
    console.log(values); // 其中p4失敗,且沒有主動捕獲p4異常,所以then()永遠走不到這裏
}).catch(function(err) {
    console.log(err); // 4
});

// 情況3:promise有一個reject,且reject主動捕獲異常
Promise.all([p1, p2, p5]).then(values => {
    console.log(values); // 其中p5失敗,但是主動捕獲了p5的異常,所以進入then() [1,2,5]
}).catch(function(err) {
    console.log(err);
});

// 情況4:使用Promise.allSettled
Promise.allSettled([p1, p2, p4]).then(values => {
    console.log(values); // 其中p4失敗,但是使用Promise.allSettled,所以進入then()返回一個帶有對象數據新的Promise
}).catch(function(err) {
    console.log(err);
});

上面代碼的執行情況
image.png

Promise.all 異常處理

1.主動對每個請求的catch做處理

主動對每個失敗的promise請求的catch做處理,使其正常的請求能返回。

例如:var p5 = Promise.reject(5).catch((e) => e);

Promise.all[]返回來的values數組,即使該請求失敗了,在values數組也會返回你主動catch返回來的內容,一般可以是接口請求的錯誤信息或者是設置爲undefined,然後在業務代碼中,根據values數組的值判斷做不同處理。達到一個接口失敗不影響其他接口返回結果的目的。

2.使用Promise.allSettled(iterable)方法

  • 接收一個 Promise 數組,執行結果返回一個成功的 Promise
  • 返回 Promise 狀態爲成功
  • 返回 Promise 的值是一個數組

// 情況4:使用Promise.allSettled

Promise.allSettled([p1, p2, p4]).then(values => {

console.log(values); // 其中p4失敗,但是使用Promise.allSettled,所以進入then()返回一個帶有對象數據新的Promise

}).catch(function(err) {

console.log(err);

});

Promise.allSettled

MDN文檔

ES2020中,JavaScript提供了一個新語法Promise.allSettled。

無論參數實例是否reject,最終Promise.allSettled內部都會resolve,只不過會添加一個狀態status來記錄對應的參數實例是否執行成功。我們可以依據這個狀態去過濾掉rejected的數據,只操作fulfilled的數據,就會得到我們想要的業務邏輯了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章