JavaScript 在 ES2020 中引入了 Promise.allSettled,以便更輕鬆地處理多個非同步操作。與 Promise.all 不同,Promise.allSettled 在 Promise 被拒絕時會短路,Promise.allSettled 可確保您從所有 Promise 中獲得結果,無論它們成功還是失敗。
在本教程中,我將引導您創建自己的 Promise.allSettled 實現,重點是從頭開始建立它。我們還將探索 Promise 在幕後如何運作,幫助您了解使 JavaScript 如此強大的異步行為。
在開始寫程式之前,讓我們先來分解 Promise.allSettled 的作用:
陣列中的每個物件包含:
const promises = [ Promise.resolve('Success'), Promise.reject('Failure'), Promise.resolve('Complete') ]; Promise.allSettled(promises).then(results => { console.log(results); });
輸出:
[ { status: 'fulfilled', value: 'Success' }, { status: 'rejected', reason: 'Failure' }, { status: 'fulfilled', value: 'Complete' } ]
當您需要等待所有 Promise 完成時,無論它們成功或失敗,此方法都是理想的選擇。
儘管現代瀏覽器中現已提供此功能,但您自己實現它可以讓您更深入地了解 JavaScript Promise 的工作原理。另外,它還確保與本身不支援 ES2020 功能的舊環境相容。
我們將建立一個名為 allSettled 的函數,它模仿 Promise.allSettled 的行為。讓我們逐步建立這個:
函數接受一組 Promise 並傳回一個新的 Promise。當所有輸入的承諾都解決(解決或拒絕)時,這個新的承諾將得到解決。
function allSettled(promises) { // This will return a new promise that resolves when all promises settle return new Promise((resolve) => { // Implementation goes here }); }
對於數組中的每個 Promise,我們需要追蹤它是解決還是拒絕。我們將用 .then() 和 .catch() 包裝每個 Promise 以捕捉其狀態:
function allSettled(promises) { return new Promise((resolve) => { let results = []; let count = 0; promises.forEach((promise, index) => { // Wrap the promise with a .then() and .catch() to capture the result promise .then((value) => { results[index] = { status: 'fulfilled', value }; }) .catch((reason) => { results[index] = { status: 'rejected', reason }; }) .finally(() => { count++; // Once all promises have settled, resolve the outer promise if (count === promises.length) { resolve(results); } }); }); }); }
1。創建外部承諾:
allSettled 函數傳回一個新的 Promise。當所有輸入承諾都解決後,此承諾將得到解決。
2。循環 Promise:
我們使用 .forEach 迴圈遍歷 Promise 陣列。對於每個承諾,我們使用 .then() (對於已解決的承諾)和 .catch() (對於拒絕的承諾)來追蹤其結果。
3。記錄結果:
每個 Promise 的結果都儲存在 results 陣列中。如果承諾得到解決,則該物件包含 { status: 'fulfilled', value }。如果拒絕,則儲存 { status: 'rejected', Reason }.
4。計算已達成的承諾:
我們使用計數變數來追蹤已解決的承諾數量。每次 Promise 完成時(透過 .then() 或 .catch()),我們都會增加計數。一旦 count 等於輸入陣列的長度,我們就用結果陣列解析外部承諾。
現在,讓我們來測試一下這個自訂實作:
const promises = [ Promise.resolve('Success'), Promise.reject('Failure'), Promise.resolve('Complete') ]; Promise.allSettled(promises).then(results => { console.log(results); });
輸出:
[ { status: 'fulfilled', value: 'Success' }, { status: 'rejected', reason: 'Failure' }, { status: 'fulfilled', value: 'Complete' } ]
正如預期的那樣,該函數等待所有 Promise 解決,結果數組為我們提供有關每個 Promise 的詳細信息,包括它是解決還是拒絕。
為了加強理解,讓我們來分解 Promise 的工作原理:
操作成功完成後已解決(已完成)。
操作失敗時被拒絕。
滿足或拒絕時結算
then() 方法允許我們指定一個在 Promise 解決時要執行的函數,而 catch() 允許我們處理拒絕。使用finally() 確保我們處理承諾結算(成功或失敗)而不會重複。
自己實現 Promise.allSettled 是從根本上理解 Promise 如何運作的絕佳方式。關鍵要點是 Promise.allSettled 會等待所有 Promise 完成,這與 Promise.all 不同,Promise.all 在遇到拒絕時會停止。
透過從頭開始實現這一點,您也學習如何以乾淨且有效率的方式處理多個非同步操作。現在,您可以使用這些知識在任何 JavaScript 環境中處理 Promise,包括那些本身不支援現代功能的環境。
以上是教學:在 JavaScript 中從頭開始實作 Polyfills Promise.allSettled的詳細內容。更多資訊請關注PHP中文網其他相關文章!