首頁  >  文章  >  web前端  >  教學:在 JavaScript 中從頭開始實作 Polyfills Promise.allSettled

教學:在 JavaScript 中從頭開始實作 Polyfills Promise.allSettled

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-10-26 01:06:02619瀏覽

Tutorial: Implementing Polyfills Promise.allSettled From Scratch in JavaScript

JavaScript 在 ES2020 中引入了 Promise.allSettled,以便更輕鬆地處理多個非同步操作。與 Promise.all 不同,Promise.allSettled 在 Promise 被拒絕時會短路,Promise.allSettled 可確保您從所有 Promise 中獲得結果,無論它們成功還是失敗。

在本教程中,我將引導您創建自己的 Promise.allSettled 實現,重點是從頭開始建立它。我們還將探索 Promise 在幕後如何運作,幫助您了解使 JavaScript 如此強大的異步行為。

什麼是 Promise.allSettled?

在開始寫程式之前,讓我們先來分解 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 完成時,無論它們成功或失敗,此方法都是理想的選擇。

為什麼要自己實作 Promise.allSettled?

儘管現代瀏覽器中現已提供此功能,但您自己實現它可以讓您更深入地了解 JavaScript Promise 的工作原理。另外,它還確保與本身不支援 ES2020 功能的舊環境相容。

實施 Promise.allSettled 的逐步指南

我們將建立一個名為 allSettled 的函數,它模仿 Promise.allSettled 的行為。讓我們逐步建立這個:

第 1 步:建立包裝函數

函數接受一組 Promise 並傳回一個新的 Promise。當所有輸入的承諾都解決(解決或拒絕)時,這個新的承諾將得到解決。

function allSettled(promises) {
  // This will return a new promise that resolves when all promises settle
  return new Promise((resolve) => {
    // Implementation goes here
  });
}

步驟 2:處理每個 Promise

對於數組中的每個 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 等於輸入陣列的長度,我們就用結果陣列解析外部承諾。

第三步:測試我們的 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 解決,結果數組為我們提供有關每個 Promise 的詳細信息,包括它是解決還是拒絕。

更深入地審視承諾

為了加強理解,讓我們來分解 Promise 的工作原理:

  • Promise 代表非同步操作的最終結果。當 Promise 建立時,它處於待處理狀態。
  • 承諾可以是:

操作成功完成後已解決(已完成)。

操作失敗時被拒絕。

滿足或拒絕時結算

then() 方法允許我們指定一個在 Promise 解決時要執行的函數,而 catch() 允許我們處理拒絕。使用finally() 確保我們處理承諾結算(成功或失敗)而不會重複。

結論

自己實現 Promise.allSettled 是從根本上理解 Promise 如何運作的絕佳方式。關鍵要點是 Promise.allSettled 會等待所有 Promise 完成,這與 Promise.all 不同,Promise.all 在遇到拒絕時會停止。

透過從頭開始實現這一點,您也學習如何以乾淨且有效率的方式處理多個非同步操作。現在,您可以使用這些知識在任何 JavaScript 環境中處理 Promise,包括那些本身不支援現代功能的環境。

以上是教學:在 JavaScript 中從頭開始實作 Polyfills Promise.allSettled的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn