runPool<T>() bounded async worker pool
TypeScript
export type PoolResult<T> =
| { status: 'fulfilled'; value: T }
| { status: 'rejected'; reason: unknown };
/** Run promise-returning tasks with a fixed concurrency, preserving task order. */
export async function runPool<T>(tasks: readonly (() => Promise<T>)[], concurrency = 4): Promise<PoolResult<T>[]> {
const size = Math.max(1, Math.min(concurrency, tasks.length));
const results: PoolResult<T>[] = new Array(tasks.length);
const queue = tasks.map((task, index) => ({ task, index }));
const worker = async (): Promise<void> => {
for (;;) {
const next = queue.shift();
if (next === undefined) return;
try {
results[next.index] = { status: 'fulfilled', value: await next.task() };
} catch (reason) {
results[next.index] = { status: 'rejected', reason };
}
}
};
await Promise.all(Array.from({ length: size }, () => worker()));
return results;
}
// const pages = await runPool(urls.map((url) => () => getJson(url)), 8);