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

2024年3月6日

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

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 上追蹤我們