Async JavaScript
Concurrency Limits & Backpressure
JavaScript can start many async operations, but remote services, memory, CPU, file descriptors, queues, and databases are finite. Concurrency limits and backpressure keep throughput from becoming self-inflicted denial-of-service.
- Async is not unlimited parallelism
- Concurrency limits cap in-flight work
- Backpressure lets consumers slow producers
- Retries need budgets
- Rate limits are external constraints
async function mapLimit(items, limit, fn) {
const results = []
const executing = new Set()
for (const item of items) {
const p = Promise.resolve().then(() => fn(item))
results.push(p)
executing.add(p.finally(() => executing.delete(p)))
if (executing.size >= limit) {
await Promise.race(executing)
}
}
return Promise.all(results)
}