Async & Promiseshard

Implement Promise pool with concurrency limit

Given async task functions and a concurrency limit, implement a scheduler that runs at most N tasks in parallel and returns results in original order.

Asked at Meta, TikTok, Stripe

#promises#concurrency#scheduling

Answer

async function runWithLimit(tasks, limit) {
  if (limit <= 0) throw new Error('limit must be > 0')
  const results = new Array(tasks.length)
  let nextIndex = 0

  async function worker() {
    while (nextIndex < tasks.length) {
      const current = nextIndex
      nextIndex++
      results[current] = await tasks[current]()
    }
  }

  const workers = Array.from(
    { length: Math.min(limit, tasks.length) },
    () => worker()
  )

  await Promise.all(workers)
  return results
}

// Usage
const tasks = [
  () => Promise.resolve(1),
  () => new Promise((r) => setTimeout(() => r(2), 30)),
  () => Promise.resolve(3),
]
runWithLimit(tasks, 2).then(console.log) // [1, 2, 3]

Practise more Async & Promises questions →