Resolve Promises Sequentially
getPromiseByIndex(i) returns the promise for index i, or null when there are none left.
Write promiseAllSync(getPromiseByIndex, count) that resolves each one in order — the next must not start until the previous has resolved — and resolves with an array of the values.
Build the chain with .then(). The interviewer asked for it without async/await on purpose.
Examples
const get = (i) => (i < 3
? new Promise((r) => setTimeout(() => r(i * 10), 100))
: null);
await promiseAllSync(get, 3);[0, 10, 20] // after ~300msConstraints
- 0 <= count <= 10
- A rejection anywhere rejects the whole result
Notes
- Reassigning one `chain` variable inside a loop is the idiom: `chain = chain.then(...)`.
Hints
Resolve Promises Sequentially (reference solution)
One way to do it. The Editorial tab walks through why it is written this way.
Solution
1function promiseAllSync(getPromiseByIndex, count) {
2 const results = [];
3 let chain = Promise.resolve();
4 for (let i = 0; i < count; i += 1) {
5 chain = chain.then(() => {
6 const promise = getPromiseByIndex(i);
7 if (promise === null || promise === undefined) return undefined;
8 return promise.then((value) => { results.push(value); });
9 });
10 }
11 return chain.then(() => results);
12}Editorial: Resolve Promises Sequentially
Sequential is a chain, not a loop
Calling every getter up front starts every promise immediately, and no amount of awaiting afterwards makes them sequential — the work is already in flight. Sequential means the next call happens inside the previous .then.
Approach
One chain variable, reassigned each iteration. The loop builds the chain; nothing runs until the previous link resolves.
Implementation
function promiseAllSync(getPromiseByIndex, count) { const results = []; let chain = Promise.resolve(); for (let i = 0; i < count; i += 1) { chain = chain.then(() => { const promise = getPromiseByIndex(i); if (promise === null || promise === undefined) return undefined; return promise.then((value) => { results.push(value); }); }); } return chain.then(() => results); }
Worth knowing
The interviewer asked for this without async/await deliberately: written as a fold over promises, it is obvious that each link creates its promise only when reached. The async version reads more naturally but hides that.
A rejection anywhere breaks the chain and propagates, so the result rejects — matching Promise.all's fail-fast behaviour even though nothing runs in parallel.