We use cookies (including Google cookies) to personalize ads and analyze traffic. By continuing to use our site, you accept our Privacy Policy.

Execute Asynchronous Functions in Parallel

Difficulty: Medium


Problem Description

Given an array of asynchronous functions, return a new promise. Each function in the array accepts no arguments and returns a promise. All the promises should be executed in parallel. The promise resolves when all the promises returned from functions were resolved successfully in parallel, returning an array of all the resolved values. The promise rejects when any of the promises were rejected, with the reason of the first rejection.


Key Insights

  • Each function in the array returns a promise that needs to be executed.
  • All promises must be executed in parallel.
  • The final promise must resolve with an array of results or reject with the reason of the first failure.
  • We cannot use the built-in Promise.all function; we need to manage promise execution manually.

Space and Time Complexity

Time Complexity: O(n) - where n is the number of functions, as we initiate all promises simultaneously. Space Complexity: O(n) - for storing the results of the promises in an array.


Solution

To solve the problem, we will:

  1. Create a new promise that will handle the execution of the asynchronous functions.
  2. Utilize an array to store the results of the resolved promises.
  3. Keep track of the number of promises resolved and the first rejection encountered.
  4. For each function, invoke it and attach .then() and .catch() handlers.
  5. If all promises resolve, the final promise resolves with the array of results; if any promise rejects, it rejects immediately with the reason of that rejection.

Code Solutions

function promiseAll(functions) {
    return new Promise((resolve, reject) => {
        const results = [];
        let completed = 0;
        let hasRejected = false;
        let firstError = null;

        functions.forEach((func, index) => {
            func().then(result => {
                if (hasRejected) return; // Ignore further resolutions if already rejected
                results[index] = result; // Store the result in order
                completed++; // Increment completed promise count
                if (completed === functions.length) {
                    resolve(results); // Resolve with all results if all completed
                }
            }).catch(error => {
                if (!hasRejected) {
                    hasRejected = true; // Mark as rejected
                    firstError = error; // Store the error
                    reject(firstError); // Reject with the first error encountered
                }
            });
        });
    });
}
← Back to All Questions