作者:Dmitri Pavlutin
譯者:前端小智
來源:dmitripavluti
有夢想,有乾貨,微信搜尋 【大遷世界】 關注這個在凌晨還在刷碗的刷碗智。
本文 GitHub https://github.com/qq449245884/xiaozhi 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。
Promise.allSettled()
方法返回一個在所有給定的 promise 都已經 fulfilled
或 rejected
後的 promise
,並帶有一個物件陣列,每個物件表示對應的 promise 結果。
接著,我們來看看 Promise.allSettled()
是如何工作的。
1. Promise.allSettled()
Promise.allSettled()
可用於並行執行獨立的非同步操作,並收集這些操作的結果。
該函式接受一個 promise
陣列(通常是一個可迭代物件)作為引數:
const statusesPromise = Promise.allSettled(promises);
當所有的輸入 promises
都被 fulfilled
或 rejected
時,statusesPromise
會解析為一個具有它們狀態的陣列
{ status: 'fulfilled', value: value }
— 如果對應的 promise 已經fulfilled
- 或者
{status: 'rejected', reason: reason}
如果相應的 promise 已經被rejected
在解析所有 promises 之後,可以使用 then
語法提取它們的狀態:
statusesPromise.then(statuses => {
statuses; // [{ status: '...', value: '...' }, ...]
});
或者使用 async/await
語法:
const statuses = await statusesPromise;
statuses; // [{ status: '...', value: '...' }, ...]
2. 取水果和蔬菜
在深入研究 Promise.allSettle()
之前,我們先定義兩個簡單的 helper
函式。
首先,resolveTimeout(value, delay)
返回一個 promise ,該 promise 在經過 delay
時間後用 value
來實現
function resolveTimeout(value, delay) {
return new Promise(
resolve => setTimeout(() => resolve(value), delay)
);
}
第二,rejectTimeout(reason, delay)
- 返回一個 promise,在經過 delay
時間後拒絕reason
。
最後,我們使用這些輔助函式來試驗 promise.allsettle()
。
2.1 All promises fulfilled
我們同時訪問當地雜貨店的蔬菜和水果。訪問每個列表是一個非同步操作:
const statusesPromise = Promise.allSettled([
resolveTimeout(['potatoes', 'tomatoes'], 1000),
resolveTimeout(['oranges', 'apples'], 1000)
]);
// wait...
const statuses = await statusesPromise;
// after 1 second
console.log(statuses);
// [
// { status: 'fulfilled', value: ['potatoes', 'tomatoes'] },
// { status: 'fulfilled', value: ['oranges', 'apples'] }
// ]
線上事例:https://codesandbox.io/s/all-...
Promise.allSettled([...])
返回一個 promise statusesPromise
,該 promise 在1秒內解決,就在蔬菜和水果被解決之後,並行地解決。
statusesPromise
解析為一個包含狀態的陣列。
- 陣列的第一項包含有蔬菜的已完成狀態:
status: 'fulfilled', value: ['potatoes', 'tomatoes'] }
- 同樣的方式,第二項是水果的完成狀態:
{ status: 'fulfilled', value: ['oranges', 'apples'] }
2.2一個 promise 被拒絕
想象一下,在雜貨店裡已經沒有水果了。在這種情況下,我們拒絕水果的 promise。
promise.allsettle()
在這種情況下如何工作?
const statusesPromise = Promise.allSettled([
resolveTimeout(['potatoes', 'tomatoes'], 1000),
rejectTimeout(new Error('Out of fruits!'), 1000)
]);
// wait...
const statuses = await statusesPromise;
// after 1 second
console.log(statuses);
// [
// { status: 'fulfilled', value: ['potatoes', 'tomatoes'] },
// { status: 'rejected', reason: Error('Out of fruits!') }
// ]
線上事例:https://codesandbox.io/s/one-...
Promise.allSettled([...])
返回的 promise 在 1
秒後解析為一個狀態陣列:
- 陣列的第一項,蔬菜
promise
成功解析:{ status: 'fulfilled', value: ['potatoes', 'tomatoes'] }
- 第二項,因為水果 promise 被拒絕,所以是一個拒絕狀態:
{ status: 'rejected', reason: Error('Out of fruits') }
即使輸入陣列中的第二個 promise 被拒絕,statusesPromise
仍然會成功解析一個狀態陣列。
2.3 所有的 promises 都被 rejected
如果雜貨店裡的蔬菜和水果都賣光了怎麼辦?在這種情況下,兩個 promise 都會被拒絕。
const statusesPromise = Promise.allSettled([
rejectTimeout(new Error('Out of vegetables!'), 1000),
rejectTimeout(new Error('Out of fruits!'), 1000)
]);
// wait...
const statuses = await statusesPromise;
// after 1 second
console.log(statuses);
// [
// { status: 'rejected', reason: Error('Out of vegetables!') },
// { status: 'rejected', reason: Error('Out of fruits!') }
// ]
線上事例:https://codesandbox.io/s/all-...
在這種情況下,statusesPromise
仍然成功地解析為一個狀態陣列。然而,該陣列包含被拒絕的promise 的狀態。
3.總結
Promise.allSettled(promises)
可以並行地執行 promise,並將狀態(fulfilled 或reject)收集到一個聚合陣列中。
Promise.allSettled(...)
在你需要執行平行和獨立的非同步操作並收集所有結果時非常有效,即使某些非同步操作可能失敗。
~~ 完,我是刷碗智,你們的點贊及在看是對我刷碗最大的認可。
編輯中可能存在的bug沒法實時知道,事後為了解決這些bug,花了大量的時間進行log 除錯,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug。
原文:https://dmitripavlutin.com/pr...
交流
文章每週持續更新,可以微信搜尋【大遷世界 】第一時間閱讀,回覆【福利】有多份前端視訊等著你,本文 GitHub https://github.com/qq449245884/xiaozhi 已經收錄,歡迎Star。