理解 JavaScript Promise 方法:all、race、any、allSettled
此文章是 FrontendMaster 上的 Advanced Web Development Quiz 課程筆記
問題
Connect the Promise methods to the right output
Match the answers to the correct options.
const promises = [
new Promise((res) => setTimeout(() => res(1), 200)),
new Promise((res) => setTimeout(() => res(2), 100)),
new Promise((_, rej) => setTimeout(() => rej(3), 100)),
new Promise((res) => setTimeout(() => res(4), 300)),
];
Promise[METHOD](promises)
.then(res => console.log("Result:", res))
.catch(e => console.log("Error:", e))[1] all
[2] race
[3] any
[4] allSettled
[a] Result: 2
[b] Error: 3
[c] Result: [{...}, {...}, {...}, {...}]
[d] Result: 2Promise
這題在比較 Promise.all、Promise.race、Promise.any、Promise.allSettled 的差異
這四個方法都可以傳入一個可以被迭代的參數,通常用陣列放一系列的 Promise,而回傳的值則各自有不同的結果,要依據情境來選擇適合的方法
Promise.all
參數中的所有 Promise 都會同時開始執行,並回傳一個 Promise 或空陣列
回傳一個 Promise,有以下幾種可能:
- 已經
fulfilled:如果傳入的參數 (陣列)為空,會直接回傳一個空陣列 - 非同步完成 (Asynchronously fulfilled):只要參數陣列內的所有
Promise都fulfilled(如果任何參數不是Promise不影響結果),Promise.all()會非同步地fulfilled,並且該回傳的fulfillment value是一個包含所有fulfillment values的陣列,順序與傳入的primise順序相同,不受完成順序影響 - 非同步拒絕 (Asynchronously rejected):只要「任何」參數陣列內的
Promise出現rejected,此時Promise.all()就會立刻reject,rejection reason會是第一個被rejected的Promise的rejection reason
用途:有一系列的 Promise 全部都必須成功拿到結果,但是不在意執行順序,一旦有任何錯誤就要執行錯誤處理
Promise.race
顧名思義,這是一個賽跑,目的是要取得第一個完成的結果,而且是不在乎他的結果是 resolve 或 reject,最後都回傳一個 Promise
回傳一個 Promise,有以下幾種可能:
- 傳入參數(陣列)如果不為空:則最後會回傳第一個有結果的
Promise,並且不在意結果是resolve或reject,如果其中有非同步的參數,那麼仍然會回傳Promise - 傳入參數(陣列)如果為空:回傳的
Promise會是一個永遠pending的狀態
用途:有一系列的 Promise,要同時執行,但只需要第一個最快執行完成的結果,結果可能是 resolve 或 reject
Promise.any
跟 Promise.race 有點像,差別在於 Promise.any 會優先回傳 resolve 的 Promise
回傳一個 Promise,有以下幾種可能:
- 已經
fulfilled:傳入參數(陣列)如果為空,立刻回傳一個包含AggregateError的rejection,它的errors會是空陣列 - 非同步完成 (Asynchronously fulfilled):任一
promisefulfills時,會非同步地fullfilled,fulfillment value是第一個被fulfilled的promise。而其他promises就會立刻被截斷。 - 非同步拒絕 (Asynchronously rejected):當所有的
promises都reject時,會非同步地rejected,rejection reason會是一個AggregateError
用途:有一系列的 Promise 要同時執行,但只需要第一個最快執行完成且 fullfilled 的結果
Promise.allSettled
最後這個蠻實用的,會等所有的 Promise 都執行完成,一次回傳全部 Promise
回傳一個 Promise(沒有 "reject" ),有以下幾種可能:
- 已經
fulfilled:傳入參數(iterable)為空時回傳此結果 - 非同步完成 (Asynchronously fulfilled):參數(iterable)中
Promise都完成時 (resolve或reject都可以),fulfillment value會是一個物件陣列,每個物件代表每個Promise的結果,順序與傳入的Promises順序相同,不受完成順序影響。此物件包含以下屬性status:字串;"fulfilled"或"rejected"value:當 status 是"fulfilled"才會有這個值。包含Promise被fulfilled的值reason:當 status 是"rejected"才會有這個值。包含該 promise 被 rejected 的原因
即使傳入的參數(陣列)不為空但不包含任何
pending promises,回傳的 Promise 仍然會是非同步fulfilled
用途:有一系列的 Promise 要同時執行,會不論執行結果全部回傳
答案
[1] [b]
[2] [d]
[3] [a]
[4] [c]