[Medium] LeetCode JS 30 - 2721. Execute Asynchronous Functions in Parallel (手寫 Promise.all)

2024年3月6日

💎 加入 E+ 成長計畫 與超過 400+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源

LeetCode 30 Days of JavaScript

本題來自 LeetCode 的 30 天 JacaScript 挑戰

2721. Execute Asynchronous Functions in Parallel (手寫 Promise.all)

題目描述

給定一個非同步函式陣列 functions,陣列中的每個函式都不接受任何參數,並且每個陣列都會回傳一個 Promise,且所有 Promise 都應並行執行。該函式最終會回傳一個 promise

promise 的解析 (resolve) 條件:

  • 當  functions  中返回的所有 Promise 都成功並行解析時,該函釋回傳的 promise 會解析。promise  的解析值應為一個陣列,其中包含與  functions  中的順序相同的已解析值。當陣列中的所有非同步函式并行執行完成後,promise  才解析。

promise 的拒絕 (reject) 情況:

  • 當  functions  中返回的任何 Promise 被拒絕時。promise  也應以第一個拒絕的原因拒絕。

此題不得使用 JavaScript 內建的 Promise.all 函式來解。

// 範例一

輸入:functions = [ () => new Promise(resolve => setTimeout(() => resolve(5), 200)) ]
輸出:{"t": 200, "resolved": [5]}
解釋:
唯一一個函式在 200 毫秒後解析,值為 5

// 範例二
輸入:functions = [ () => new Promise(resolve => setTimeout(() => resolve(1), 200)), () => new Promise((resolve, reject) => setTimeout(() => reject("Error"), 100)) ]
輸出:{"t": 100, "rejected": "Error"}
解釋:
由於其中一個 Promise 被拒絕,返回的 Promise 也會在同一時間以相同的錯誤原因被拒絕。

本題解答

以下是本題的解答,詳細解題思路可以在 E+ 成長計畫看到。如果想練習更多題目,推薦可以到 GreatFrontEnd 上練習

解法

var promiseAll = async function (promises) {
  const outputs = [];

  let resolveCounter = 0;

  return new Promise((resolve, reject) => {
    promises.forEach((promise, index) => {
      promise()
        .then((value) => {
          outputs[index] = value;

          resolveCounter += 1;

          if (resolveCounter === promises.length) {
            resolve(outputs);
          }
        })
        .catch(reject);
    });
  });
};
🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們