tezvyn:

Implement inSequence(tasks) to execute promise-returning functions sequentially

AI-drafted, machine-checkedSource: developer.mozilla.orgadvanced
Implement inSequence(tasks) to execute promise-returning functions sequentially

Tests async/await control flow versus Promise.all parallelism. A strong answer uses a for-of loop with await inside an async function, accumulates results in order, and stops cleanly on rejection. Red flag: suggesting Promise.all or forEach with await.

WHAT THIS TESTS: This question tests whether you can orchestrate asynchronous operations sequentially rather than concurrently. Many senior engineers default to Promise.all for every array-of-promises scenario, so the interviewer wants to see if you understand when to block and await. It also surfaces knowledge of closure behavior inside loops, error propagation in async functions, and why certain array methods break sequential semantics.

A GOOD ANSWER COVERS: A good answer hits four things in order. First, declare an async function inSequence that accepts an array of task functions. Second, initialize an empty results array. Third, use a standard for loop or for-of loop to iterate the tasks, calling each one and awaiting the returned promise before pushing the result into the array. Fourth, return the results array, relying on the implicit promise wrapper of the async function. A senior candidate also mentions that if any task rejects, the async function automatically rejects and no subsequent tasks run, which is usually the desired behavior for true sequential dependency.

COMMON WRONG ANSWERS: Common wrong answers reveal misunderstanding of the event loop. Using tasks.forEach with an async callback fires every task immediately because forEach does not await the callback it invokes. Returning Promise.all(tasks.map(t => t())) runs everything concurrently and defeats the purpose. Another red flag is a manual reduce chain building a promise ladder with .then; while it technically serializes, it is verbose, harder to debug, and often mishandles return types or errors. A subtle trap is forgetting that the array contains functions, not promises, so awaiting the element itself without calling it is a bug.

LIKELY FOLLOW-UPS: Interviewers often follow up by asking how to add concurrency limits, such as running tasks in batches of three. They may also ask what happens if a task throws synchronously before returning a promise, or how to implement a retry with exponential backoff inside the loop. Another variant is returning results in the same order even when some tasks are allowed to run in parallel, which shifts the solution toward a Promise.all with index tracking or a task queue.

ONE CONCRETE EXAMPLE: Imagine three tasks where task one takes 100 milliseconds, task two takes 50 milliseconds, and task three takes 25 milliseconds. With Promise.all the total time is roughly 100 milliseconds. With inSequence the total time is 175 milliseconds because each awaits the previous. A strong candidate might mention this trade-off explicitly and note that inSequence is appropriate when later tasks depend on earlier side effects, such as writing files in order or rate-limited API calls.

Source: developer.mozilla.org

Read the original → developer.mozilla.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.