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