Skip to content

Instantly share code, notes, and snippets.

@juliendargelos
Last active July 9, 2025 10:28
Show Gist options
  • Save juliendargelos/c5a3e1b54d94edcf764d841a003d0951 to your computer and use it in GitHub Desktop.
Save juliendargelos/c5a3e1b54d94edcf764d841a003d0951 to your computer and use it in GitHub Desktop.
Concurrently run an asynchronous function on a list of items given a concurrency limit.
/**
* Concurrently run an asynchronous function on a list of items given a
* concurrency limit. A concurrency limit equal to Infinity makes this function
* behave like `Promise.all`.
*
* @params items - List of items to process
* @params run - Asynchronous function to run for each item
* @params concurrency - Maximum number of concurrent executions
* @return A Promise that resolves to an array of results
*/
async function concurrent<Item = any, Result = any>(
items: Iterable<Item>,
run: (item: Item, index: number) => Promise<Result>,
concurrency: number = Infinity
): Promise<Result[]> {
const pool: (() => void)[] = []
concurrency = Math.max(1, Math.floor(concurrency || 0))
return Promise.all([...items].map((item, index) => (
new Promise<Result>((resolve, reject) => {
const start = () => run(item, index)
.then((result) => { pool.pop()?.(), resolve(result) })
.catch((error) => { pool.splice(0), reject(error) })
index < concurrency ? start() : pool.unshift(start)
})
)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment