[Medium] LeetCode JS 30 - 2721. Execute Asynchronous Functions in Parallel
March 6, 2024
LeetCode 30 Days of JavaScript
This question is from LeetCode's 30 Days of JavaScript Challenge
2721. Execute Asynchronous Functions in ParallelQuestion Prompt
Given an array of asynchronous functions functions
, return a new promise promise
. Each function in the array accepts no arguments and returns a promise. All the promises should be executed in parallel.
promise
resolves:
- When all the promises returned from
functions
were resolved successfully in parallel. The resolved value ofpromise
should be an array of all the resolved values of promises in the same order as they were in thefunctions
. Thepromise
should resolve when all the asynchronous functions in the array have completed execution in parallel.
promise
rejects:
- When any of the promises returned from
functions
were rejected.promise
should also reject with the reason of the first rejection.
Please solve it without using the built-in Promise.all
function.
// Example 1:
Input: functions = [
() => new Promise(resolve => setTimeout(() => resolve(5), 200))
]
Output: {"t": 200, "resolved": [5]}
Explanation:
promiseAll(functions).then(console.log); // [5]
The single function was resolved at 200ms with a value of 5.
Solutions
Looking to practice more questions like these? We recommend GreatFrontEnd, the best platform for honing your frontend interview skills!
First, we can check if the input array, promises
, is empty, it means there are no promises to coordinate. We directly resolve with an empty array using Promise.resolve([])
.
Then, we create an output array called outputs
to store the results of our promises. It's the same size as the input array to maintain the correct order. Also, we create resolveCounter
to track how many promises have successfully resolved.
For the core, we construct a new Promise
. This is important as our promiseAll
function itself returns a promise that the caller can depend on. We use forEach
, we go through each promise in the input.
With .then
, we handle what happens when a promise resolves. We store the resolved value
in its corresponding position in the outputs
array. We increase resolveCounter
.
If resolveCounter
matches the total number of promises, it means all the promises have been resolved, so we resolve
the primary promise.
For error handling, we use .catch
to take care of it. if any promise rejects, we immediately reject
the primary promise
var promiseAll = function (promises) {
// Base case: If there are no promises, immediately resolve with an empty array
if (promises.length === 0) {
return Promise.resolve([]);
}
// Create an array to hold the results of each promise
const outputs = new Array(promises.length);
// Counter to track how many promises have resolved successfully
let resolveCounter = 0;
return new Promise((resolve, reject) => {
// Iterate over each promise in the input array
promises.forEach((promise, index) => {
// Invoke the promise immediately
promise()
.then((value) => {
// Store the resolved value in the corresponding index of the outputs array
outputs[index] = value;
// Increment the counter of resolved promises
resolveCounter += 1;
// If all promises have resolved, resolve the main promise with the outputs array
if (resolveCounter === promises.length) {
resolve(outputs);
}
})
.catch((err) => {
// If any promise rejects, reject the main promise with the error
reject(err);
});
});
});
};
Code without comments
var promiseAll = function (promises) {
if (promises.length === 0) {
return Promise.resolve([]);
}
const outputs = new Array(promises.length);
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);
});
});
};