[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);
});
});
};