Skip to main content

Parallel Execution of Promises for Individual Results Retrieval - Solution & Explanation

MediumPremiumFree on FleetCode5 min read
Practice this problem

Problem Statement

Given an array functions, return a promise promise. functions is an array of functions that return promises fnPromise. Each fnPromise can be resolved or rejected.  

If fnPromise is resolved:

    obj = { status: "fulfilled", value: resolved value}

If fnPromise is rejected:

    obj = { status: "rejected", reason: reason of rejection (catched error message)}

The promise should resolve with an array of these objects obj. Each obj in the array should correspond to the promises in the original array function, maintaining the same order.

Try to implement it without using the built-in method Promise.allSettled().

 

Example 1:

Input: functions = [
    () => new Promise(resolve => setTimeout(() => resolve(15), 100))
]
Output: {"t":100,"values":[{"status":"fulfilled","value":15}]}
Explanation: 
const time = performance.now()
const promise = promiseAllSettled(functions);
               
promise.then(res => {
    const out = {t: Math.floor(performance.now() - time), values: res}
    console.log(out) // {"t":100,"values":[{"status":"fulfilled","value":15}]}
})

The returned promise resolves within 100 milliseconds. Since promise from the array functions is fulfilled, the resolved value of the returned promise is set to [{"status":"fulfilled","value":15}].

Example 2:

Input: functions = [
    () => new Promise(resolve => setTimeout(() => resolve(20), 100)), 
    () => new Promise(resolve => setTimeout(() => resolve(15), 100))
]
Output: 
{
    "t":100,
    "values": [
        {"status":"fulfilled","value":20},
        {"status":"fulfilled","value":15}
    ]
}
Explanation: The returned promise resolves within 100 milliseconds, because the resolution time is determined by the promise that takes the longest time to fulfill. Since promises from the array functions are fulfilled, the resolved value of the returned promise is set to [{"status":"fulfilled","value":20},{"status":"fulfilled","value":15}].

Example 3:

Input: functions = [
    () => new Promise(resolve => setTimeout(() => resolve(30), 200)), 
    () => new Promise((resolve, reject) => setTimeout(() => reject("Error"), 100))
]
Output:
{
    "t":200,
    "values": [
        {"status":"fulfilled","value":30},
        {"status":"rejected","reason":"Error"}
    ]
}
Explanation: The returned promise resolves within 200 milliseconds, as its resolution time is determined by the promise that takes the longest time to fulfill. Since one promise from the array function is fulfilled and another is rejected, the resolved value of the returned promise is set to an array containing objects in the following order: [{"status":"fulfilled","value":30}, {"status":"rejected","reason":"Error"}]. Each object in the array corresponds to the promises in the original array function, maintaining the same order.

 

Constraints:

  • 1 <= functions.length <= 10

Approach Overview

Problem Overview: You receive an array of functions where each function returns a promise. All functions should execute in parallel, and the final promise should resolve with an array of results in the same order as the input. If any promise rejects, the overall promise rejects immediately.

Approach 1: Sequential Await (O(n) time, O(n) space)

The straightforward idea is to iterate through the array and await each promise one by one. Store each resolved value in a results array and return it after the loop finishes. This approach preserves order naturally because each promise completes before the next begins. The downside is that execution becomes sequential instead of parallel, which defeats the purpose of concurrent asynchronous work. Time complexity is O(n) but total runtime depends on the sum of all promise durations rather than the maximum duration.

This method is useful for understanding the problem and verifying result ordering, but it wastes the concurrency that promises provide. In real systems where network calls or I/O operations dominate runtime, sequential execution significantly slows performance.

Approach 2: Parallel Execution with Completion Counter (O(n) time, O(n) space)

The correct strategy launches every async function immediately and tracks completion. Create a new Promise and iterate through the input array. For each index, invoke the function and attach a .then() handler. Store the resolved value in the results array at the same index to preserve ordering.

Maintain a counter that tracks how many promises have resolved. Each successful resolution increments the counter. Once the counter equals the number of functions, resolve the outer promise with the results array. If any promise rejects, call reject immediately so the outer promise fails early.

This design ensures all promises run concurrently while still guaranteeing ordered results. The runtime complexity is O(n) because each promise is processed once. Space complexity is also O(n) for the results array and bookkeeping.

This pattern mirrors how Promise.all behaves internally. It relies heavily on concepts from JavaScript Promises, asynchronous execution in async programming, and coordination patterns commonly used in concurrency.

Recommended for interviews: Interviewers expect the parallel execution approach. The sequential method demonstrates baseline understanding but fails to utilize concurrency. The counter-based parallel strategy shows that you understand how promises resolve asynchronously while preserving deterministic output ordering.

Solution

Code

TypeScript

JavaScript

Try this approach in the editor →

Detailed Complexity Analysis

ApproachTimeSpaceWhen to Use
Sequential AwaitO(n)O(n)Simple baseline implementation when concurrency is not required
Parallel Execution with CounterO(n)O(n)General case where promises should run concurrently and results must preserve order
Built-in Promise.all PatternO(n)O(n)Production code when native Promise utilities are allowed

Video Solution

Reverse Linked List - Iterative AND Recursive - Leetcode 206 - Python • NeetCode • 539,243 views views

Watch 9 more video solutions →

Frequently Asked Questions

Is Parallel Execution of Promises for Individual Results Retrieval easy or hard?
The problem is typically classified as Medium because it requires understanding asynchronous execution and promise coordination. Developers comfortable with Promise.all and concurrent patterns usually solve it quickly, but beginners often struggle with ordering and rejection handling.
Parallel Execution of Promises for Individual Results Retrieval Python/Java solution
This problem is primarily designed for JavaScript or TypeScript because it focuses on Promise behavior. In Python, similar behavior can be implemented using asyncio.gather, while Java uses CompletableFuture.allOf to run asynchronous tasks concurrently.
How to solve Parallel Execution of Promises for Individual Results Retrieval in O(n)?
Invoke all async functions immediately inside a loop and attach a .then() handler to each returned promise. Store resolved values in a results array using the original index. Maintain a counter for completed promises and resolve the outer promise once the counter reaches n. Reject immediately if any promise fails.
What is the best approach for Parallel Execution of Promises for Individual Results Retrieval?
The optimal approach runs all promise-returning functions concurrently and tracks their completion using a results array and a counter. Each promise stores its resolved value at the corresponding index. When all promises resolve, the outer promise resolves with the ordered results. This approach runs in O(n) time and O(n) space.
Is Parallel Execution of Promises for Individual Results Retrieval asked at Google/Amazon/Meta?
Promise coordination and asynchronous execution patterns frequently appear in JavaScript interviews at companies like Amazon and Meta. Variants of implementing Promise.all or managing parallel async tasks are common frontend and full‑stack interview questions.
What data structure is used in Parallel Execution of Promises for Individual Results Retrieval?
The primary data structure is an array used to store resolved values in their original order. A simple integer counter tracks completion. The logic relies on JavaScript Promise objects and asynchronous callbacks rather than complex data structures.
What is the time complexity of Parallel Execution of Promises for Individual Results Retrieval?
The time complexity is O(n) because each promise is invoked and processed exactly once. All promises execute concurrently, so the real runtime depends on the slowest promise rather than the sum of all durations. Space complexity is O(n) for storing results.

Ready to solve this problem?

Practice Parallel Execution of Promises for Individual Results Retrieval with our built-in code editor and test cases.

Practice on FleetCode