← Questions
Run promise tasks with bounded concurrency
0
I was asked this
No reports yet. Sign in to say where you were asked it.
In TypeScript, write a scheduler that runs a list of async tasks with at most limit running at once. Each task is a function that returns a promise. Start the next task as soon as one finishes, never fail fast, and resolve with every task's outcome in the original order.
Interface
Unless you agree on a different interface with the interviewer, assume:
type Settled<T> = { status: "fulfilled"; value: T } | { status: "rejected"; reason: unknown };
function runWithLimit<T>(tasks: Array<() => Promise<T>>, limit: number): Promise<Settled<T>[]>;
- Each task factory is called exactly once. A task that throws synchronously counts as rejected, like one whose promise rejects.
- The result array is in input order, whatever order tasks finish in.
- A
limitthat is not a positive integer rejects immediately, before any task starts. An empty task list resolves to[].
Example
tasks: A (300 ms, resolves "a"), B (100 ms, rejects "boom"), C (100 ms, resolves "c")
runWithLimit(tasks, 2)
t=0 start A, B
t=100 B rejects -> start C
t=200 C resolves
t=300 A resolves
result: [{fulfilled, "a"}, {rejected, "boom"}, {fulfilled, "c"}]
Constraints
- At no moment are more than
limittasks in flight. - Works for
limitgreater than the number of tasks.
Clarifying questions
- On a rejection, keep going or stop everything?
- Results in input order or completion order?
- What should happen with
limit0, negative or fractional? - Is cancellation needed?
What a strong answer covers
- A pool of
limitworkers that each pull the next index from a shared counter, or alaunchNextcalled from each task'sfinally. - Wrapping each call in
Promise.resolve().then(task)or try/catch so synchronous throws become rejections. - Writing results by index so order is preserved; resolving only after every task settles.
- Validating
limitup front, and the empty-list case. - Deterministic tests of the cap with controllable fake promises (count in-flight tasks and assert the maximum).
Follow-ups
- Add cancellation with an
AbortSignal. - Add a per-task timeout.
- Tasks have priorities, and new tasks can be added while running.
No official answer yet. Write yours on the right and run it.
Nothing published yet.
Sign in to submit your code; every attempt is kept here.
Write and test your solution herePython in your browser, the question's tests level by level, every submission kept for you.Sign in to start coding
