25 lines
736 B
TypeScript
25 lines
736 B
TypeScript
|
|
/**
|
||
|
|
* Map `fn` over `items` with at most `limit` concurrent calls, preserving
|
||
|
|
* result order regardless of completion order.
|
||
|
|
*
|
||
|
|
* Extracted from the files page so batch fan-out paths (delete, drag-move,
|
||
|
|
* upload probing) and the shared resource-actions composable all use the
|
||
|
|
* same bounded-concurrency primitive.
|
||
|
|
*/
|
||
|
|
export async function mapLimit<T, R>(
|
||
|
|
items: readonly T[],
|
||
|
|
limit: number,
|
||
|
|
fn: (item: T) => Promise<R>
|
||
|
|
): Promise<R[]> {
|
||
|
|
const out = new Array<R>(items.length);
|
||
|
|
let next = 0;
|
||
|
|
const worker = async () => {
|
||
|
|
while (next < items.length) {
|
||
|
|
const i = next++;
|
||
|
|
out[i] = await fn(items[i]);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
await Promise.all(Array.from({ length: Math.max(0, Math.min(limit, items.length)) }, worker));
|
||
|
|
return out;
|
||
|
|
}
|