Parallel vs Sequential Promises
This question was asked at Intuit interview. Here's the link to the question
You are given two asynchronous functions to implement:
A()should resolve to the number 2 after 2 secondsB()should resolve to the number 3 after 3 seconds
Return their sum in two ways:
- Parallel execution → Total time of execution: 3 seconds
- Sequential execution → Total time of execution: 5 seconds
Examples
// After implementing A, B, sequential and parallel:
(async () => {
await evaluate(sequential, "SEQUENTIAL");
await evaluate(parallel, "PARALLEL");
})();Executing SEQUENTIAL task starts...
Task SEQUENTIAL finished in ~5000 ms with sum: 5
Executing PARALLEL task starts...
Task PARALLEL finished in ~3000 ms with sum: 5Hints
Editorial: Parallel vs Sequential Promises
Intuition
We need two async functions:
A()that resolves to2after 2 secondsB()that resolves to3after 3 seconds
Then we must return their sum in two ways:
- Sequentially (one after the other) → ~5 seconds total
- In parallel (together) → ~3 seconds total
This problem is about understanding how await controls when Promises are started vs when we wait for them.
Implementing A and B
We can reuse a helper wait(seconds) that returns a Promise which resolves after the given number of seconds:
const wait = (seconds) => { return new Promise((resolve) => { setTimeout(resolve, seconds * 1000); }); };
Using this helper, we can implement A and B:
// A resolves 2 after 2 seconds const A = async () => { await wait(2); return 2; }; // B resolves 3 after 3 seconds const B = async () => { await wait(3); return 3; };
Sequential Solution (Waterfall)
In the sequential version, we:
- Await
A()and get its result - Only after that finishes, we call and await
B() - Then we return the sum
const sequential = async () => { const a = await A(); // waits ~2s const b = await B(); // waits ~3s (starts only after A is done) return a + b; // total ~5s };
Because we start B only after A finishes, total time is roughly:
- 2 seconds + 3 seconds = 5 seconds
This is the classic async waterfall pattern.
Parallel Solution (Using Promise.all)
To run both tasks in parallel, we must:
- Start
A()andB()immediately (without awaiting them yet) - Use
Promise.allto await both at the same time - Sum the resolved values
const parallel = async () => { const promiseA = A(); // starts immediately const promiseB = B(); // starts immediately const [a, b] = await Promise.all([promiseA, promiseB]); return a + b; // total ~3s (dominated by B) };
Now both timers run together:
- A finishes in ~2 seconds
- B finishes in ~3 seconds
Total time is therefore about 3 seconds, the slower of the two.
Full Working Example
Here is a full reference implementation with a helper that measures execution time:
// Utility: wait for N seconds const wait = (seconds) => { return new Promise((resolve) => { setTimeout(resolve, seconds * 1000); }); }; // A resolves 2 after 2 seconds const A = async () => { await wait(2); return 2; }; // B resolves 3 after 3 seconds const B = async () => { await wait(3); return 3; }; // Sequential execution → ~5 seconds const sequential = async () => { const a = await A(); const b = await B(); return a + b; }; // Parallel execution → ~3 seconds const parallel = async () => { const [a, b] = await Promise.all([A(), B()]); return a + b; }; // Helper to measure execution time const evaluate = async (fn, label) => { const startTime = performance.now(); console.log(`Executing ${label} task starts...`); const result = await fn(); const endTime = performance.now(); console.log( `Task ${label} finished in ${Math.round(endTime - startTime)} ms with sum:`, result ); }; // Run both (async () => { await evaluate(sequential, "SEQUENTIAL"); // ~5000 ms await evaluate(parallel, "PARALLEL"); // ~3000 ms })();
Key Takeaways
awaitdoes not make code inherently parallel — if youawaitone Promise before creating the next, you get sequential execution.- To run tasks in parallel, create all Promises first, then await them together (e.g. with
Promise.all). - When tasks run in parallel, total time is roughly the time of the slowest task, not the sum of all durations.