2 · Data and boundaries · 30 MIN
Sequential awaits and bounded concurrency
Concurrency determines how many operations are in flight.
Promise.all over an already constructed list starts all those operations without imposing a concurrency limit. This worker loop reserves an index synchronously before awaiting the supplied function, limiting active work while storing each result in input order. It runs in one JavaScript event loop and does not create CPU parallelism. A failure rejects the result, but already started operations need cooperative cancellation if they should stop. Retrying a function with side effects also requires an idempotency decision.
Check empty input and invalid limits.
Read the example
async function mapLimit(values,limit,fn){
if(!Number.isInteger(limit)||limit<1)throw new Error('positive integer limit required');
const result=new Array(values.length);let next=0;
async function worker(){while(next<values.length){const index=next++;result[index]=await fn(values[index],index)}}
await Promise.all(Array.from({length:Math.min(limit,values.length)},worker));
return result;
}
console.log(await mapLimit([3,1,2],2,async n=>n*n));
Check the expected output
[9, 1, 4] (console spacing can differ); output order follows input order.
Your challenge
Instrument active work, verify the cap and add an AbortSignal contract for cancellation after failure.
Solution cost: O(n) bookkeeping plus task cost. time · O(n + c) result and c workers. space
Common trap
Bounded promises do not move CPU-heavy work off the event loop.
Study the project implementation
async function mapLimit(values,limit,fn){
if(!Number.isInteger(limit)||limit<1)throw new Error('positive integer limit required');
const result=new Array(values.length);let next=0;
async function worker(){while(next<values.length){const index=next++;result[index]=await fn(values[index],index)}}
await Promise.all(Array.from({length:Math.min(limit,values.length)},worker));
return result;
}
console.log(await mapLimit([3,1,2],2,async n=>n*n));
Further reading: Official documentation
Next lesson: HTTP routing and explicit responses →