Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 1x 97x 97x 97x 97x 191x 208x 208x 208x 52x 6x 6x 46x 97x 91x | /**
* Run `work` over `items` with at most `limit` in flight, settling every one.
*
* Results come back in input order whatever order they complete in, so callers that merge them
* stay deterministic.
*
* A failure that `isFatal` accepts is not settled: it rejects the whole run as soon as it is
* seen, and no further item is started. Work already in flight finishes in the background.
*/
export async function settleWithConcurrency<T, R>(
items: readonly T[],
limit: number,
work: (item: T) => Promise<R>,
isFatal: (reason: unknown) => boolean = () => false,
): Promise<PromiseSettledResult<R>[]> {
const results: PromiseSettledResult<R>[] = Array.from({ length: items.length });
let next = 0;
let stopped = false;
const worker = async (): Promise<void> => {
while (!stopped && next < items.length) {
const index = next++;
try {
results[index] = { status: 'fulfilled', value: await work(items[index] as T) };
} catch (reason) {
if (isFatal(reason)) {
stopped = true;
throw reason;
}
results[index] = { status: 'rejected', reason };
}
}
};
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));
return results;
}
|