LeetCode Problem Workspace
Execute Asynchronous Functions in Parallel
Solve the problem of executing asynchronous functions in parallel, handling resolve and reject scenarios effectively.
0
Topics
1
Code langs
0
Related
Practice Focus
Medium · Execute Asynchronous Functions in Parallel core interview pattern
Answer-first summary
Solve the problem of executing asynchronous functions in parallel, handling resolve and reject scenarios effectively.
Ace coding interviews with Interview AiBoxInterview AiBox guidance for Execute Asynchronous Functions in Parallel core interview pattern
To solve this problem, execute all asynchronous functions in parallel, handling both resolved and rejected promises. The returned promise should resolve when all functions are finished or reject if any function fails. This approach ensures efficiency while managing timeouts and errors gracefully.
Problem Statement
You are given an array of functions that return promises. Each function should be executed in parallel, and the result should be tracked until all promises either resolve or one rejects. The final promise should resolve with the results of the functions that successfully resolved, or reject with the first error encountered.
Your task is to implement a function that executes all asynchronous functions in parallel and returns a new promise. This promise should resolve or reject depending on the outcomes of the individual functions, ensuring that the overall execution is efficient and error-tolerant.
Examples
Example 1
Input: functions = [ () => new Promise(resolve => setTimeout(() => resolve(5), 200)) ]
Output: {"t": 200, "resolved": [5]}
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"}
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]}
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 promises
- 1 <= functions.length <= 10
Solution Approach
Execute All Promises in Parallel
Use Promise.all() to execute all asynchronous functions in parallel. Track each function’s resolution or rejection and return the final result after all promises have been handled.
Handle Rejections Efficiently
If any promise is rejected, the entire promise chain should reject immediately with the rejection reason. This prevents further execution once an error occurs.
Track Timing and Results
Record the time taken for the promises to resolve, and return both the time and the resolved values in a structured format, ensuring correct order and timing are tracked.
Complexity Analysis
| Metric | Value |
|---|---|
| Time | O(N) |
| Space | O(N) |
The time complexity of this problem is O(N), where N is the number of functions. This is because all promises are executed concurrently. The space complexity is also O(N) due to storing the results of the promises.
What Interviewers Usually Probe
- Ensure the candidate handles both resolve and reject scenarios effectively.
- Look for the correct usage of parallel execution strategies, such as Promise.all().
- Test whether the candidate can track the timing of executions and handle errors gracefully.
Common Pitfalls or Variants
Common pitfalls
- Not handling rejections properly, causing the promise to hang or resolve incorrectly.
- Incorrectly tracking the execution time or values from individual functions.
- Not using a structure that ensures the final promise resolves or rejects based on all functions.
Follow-up variants
- Implementing this solution using Promise.allSettled() instead of Promise.all() for a different error handling approach.
- Handling timeouts for individual promises and rejecting the overall promise if a timeout occurs.
- Modifying the function to return results in the same order as the functions were originally given, regardless of their resolution time.
FAQ
How do you execute asynchronous functions in parallel?
Use Promise.all() to execute multiple asynchronous functions concurrently. This method waits for all promises to resolve or rejects immediately if any promise fails.
What happens if one promise is rejected in this problem?
If one promise rejects, the returned promise also rejects immediately with the same reason, and no further execution occurs.
How do you handle timeouts in parallel execution?
Timeouts can be handled by using Promise.race() or setting explicit timeouts within each asynchronous function. This prevents long waiting times on individual promises.
What is the time complexity of executing promises in parallel?
The time complexity is O(N), where N is the number of promises, because all promises are executed simultaneously without any dependency between them.
How does GhostInterview assist in solving this problem?
GhostInterview provides a structured approach, helps manage parallel execution, tracks results, and ensures efficient handling of promise rejections.
Solution
Solution 1
#### TypeScript
async function promiseAll<T>(functions: (() => Promise<T>)[]): Promise<T[]> {
return new Promise<T[]>((resolve, reject) => {
let cnt = 0;
const ans = new Array(functions.length);
for (let i = 0; i < functions.length; ++i) {
const f = functions[i];
f()
.then(res => {
ans[i] = res;
cnt++;
if (cnt === functions.length) {
resolve(ans);
}
})
.catch(err => {
reject(err);
});
}
});
}
/**
* const promise = promiseAll([() => new Promise(res => res(42))])
* promise.then(console.log); // [42]
*/