
Problem Statement
In this problem, you are provided with an array named functions
, wherein each element of this array is an asynchronous function that returns a promise. The task is to process these functions in parallel and track their completions. The output should be a new promise, promise
, that handles the results from each of the asynchronous functions in the array.
Resolution Scenario:
promise
should resolve if all the asynchronous functions resolve their promises successfully. The result should be an array containing the resolved values of these promises, maintaining the same order as they appear in the input arrayfunctions
.Rejection Scenario:
promise
should reject if any of the asynchronous function's promises get rejected. Additionally, the rejection reason should be the reason provided by the first promise that gets rejected.
Importantly, the challenge specifies not to use the built-in Promise.all
function, which typically handles such scenarios, hence requiring a manual implementation of promise handling.
Examples
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.
Example 2
Input:
functions = [ () => new Promise(resolve => setTimeout(() => resolve(1), 200)), () => new Promise((resolve, reject) => setTimeout(() => reject("Error"), 100)) ]
Output:
{"t": 100, "rejected": "Error"}
Explanation:
Since one of the promises rejected, the returned promise also rejected with the same error at the same time.
Example 3
Input:
functions = [ () => new Promise(resolve => setTimeout(() => resolve(4), 50)), () => new Promise(resolve => setTimeout(() => resolve(10), 150)), () => new Promise(resolve => setTimeout(() => resolve(16), 100)) ]
Output:
{"t": 150, "resolved": [4, 10, 16]}
Explanation:
All the promises resolved with a value. The returned promise resolved when the last promise resolved.
Constraints
functions
is an array of functions that returns promises1 <= functions.length <= 10
Approach and Intuition
Given the constraints and explanations in the examples, let's construct the approach to solve this problem:
Initialization of Variables:
- Create an array to store the results of the promises.
- Initiate a counter to keep track of completed promises.
Handling Each Function:
- Iterate over the array of functions.
- Immediately invoke each function (since they are asynchronous and return promises).
- Attach
.then
and.catch
handlers to each promise returned by the functions.
Resolve Handling:
- In the
.then
handler, update the results array with the resolved value at the respective index. - Increment the counter of completed promises.
- If the counter indicates all promises are resolved, the main
promise
should resolve with the array of results.
- In the
Reject Handling:
- In the
.catch
handler, immediately reject the mainpromise
with the encountered error, if it is the first to fail. - Ensure to handle synchronization issues to avoid multiple rejections.
- In the
Concurrency Assurance:
- All functions are triggered in the same synchronous loop, ensuring they run in parallel.
- JavaScript’s event loop and the inherent nature of promises handle the concurrency.
By following these steps, one can mimic what Promise.all
offers but with explicit control over its internal workings, appropriately handling all given conditions from the problem statement.
Solutions
- JavaScript
var executeAllPromises = function(promisesArray) {
return new Promise((resolve, reject) => {
if(promisesArray.length === 0) {
resolve([]);
return;
}
const results = new Array(promisesArray.length).fill(null);
let completionCount = 0;
promisesArray.forEach((promise, index) => {
promise().then((result) => {
results[index] = result;
completionCount++;
if(completionCount === promisesArray.length) {
resolve(results);
}
}).catch((error) => {
reject(error);
})
});
});
};
The provided JavaScript solution demonstrates how to execute multiple asynchronous functions in parallel and gather their results. Utilize the executeAllPromises
function by passing an array of asynchronous functions (promises) that you intend to execute concurrently.
- Begin by initiating a new
Promise
which takes two functions as arguments,resolve
andreject
. - Verify if the passed
promisesArray
is empty. If it is, immediately resolve the promise with an empty array as there are no functions to execute. - Create an array
results
of the same size aspromisesArray
with all elements initially set tonull
, to store the results of each promise. - Define a counter
completionCount
to keep track of how many promises have been resolved. - Iterate over
promisesArray
usingforEach
, executing each promise. - Inside the
then
block of each promise, store the resultant value at the corresponding index in theresults
array and incrementcompletionCount
. - Continuously check if
completionCount
matches the length ofpromisesArray
. Once all promises are resolved, useresolve(results)
to return the array of results from all the promises. - Handle any promise rejections with the
catch
block. Utilizereject(error)
to throw an error out of theexecuteAllPromises
function if any individual promise fails.
This implemention ensures all provided asynchronous operations proceed in parallel, without wait time between them, resulting in efficient execution and handling of multiple asynchronous events. Use this function to manage groups of asynchronous operations that can run concurrently while gathering all their outcomes once all have completed.
No comments yet.