coding round · ~25 min
JavaScriptadvanced

Run promises with a concurrency limit

Write runWithConcurrency(tasks, limit). tasks is an array of functions that each return a promise (calling a task starts its work), and limit is a positive integer. The function returns a promise that follows these rules:

  • at most limit tasks run at the same time
  • the next task starts as soon as any running task finishes (not in fixed batches of limit)
  • it resolves with the results in the same order as tasks, not in completion order
  • if a task rejects, it rejects with that error right away and starts no more tasks

Examples:

  • with limit = 2 and tasks taking 100ms, 20ms and 20ms, the first two start immediately, the third starts at about 20ms, and the result is [r1, r2, r3]
  • runWithConcurrency([], 3) → resolves to []
  • with limit = 1 the tasks run one after another, in order

Define runWithConcurrency in the editor. 7 tests will call it.

read the related note →

solution.js
function runWithConcurrency(tasks, limit) {
  // tasks: array of functions that return promises.
  // Run at most `limit` of them at once, and resolve with
  // all results in the original order.
}

Tests⌘/Ctrl + Enter to run

resolves with results in the original order
never runs more than limit tasks at once
runs tasks one after another when limit is 1
starts the next task as soon as any task finishes (no batching)
handles a limit larger than the number of tasks
resolves with [] when there are no tasks
rejects when a task fails and starts no new tasks after that
esc