loop-controls
Version:
break/continue controls for loops and higher-order functions (sync, async, concurrent). Designed to compose with ts-pattern.
47 lines • 1.41 kB
JavaScript
import { _Break, _Continue } from "./core.js";
export async function forEachConcurrent(items, fn, { concurrency } = {}) {
if (concurrency !== undefined && concurrency < 1)
concurrency = 1;
const c = new AbortController();
const { signal } = c;
let broken = false;
let index = 0;
const ctrl = {
signal,
continue: () => { throw new _Continue(); },
break: (value) => { c.abort(); throw new _Break(value); },
};
const worker = async () => {
while (!signal.aborted) {
const i = index++;
if (i >= items.length)
return;
const item = items[i];
try {
await fn(item, ctrl, i);
}
catch (e) {
if (e instanceof _Continue)
continue;
if (e instanceof _Break) {
broken = true;
return;
}
c.abort();
throw e;
}
}
};
const workerCount = concurrency ?? items.length;
const workers = Array.from({ length: workerCount }, () => worker());
try {
await Promise.all(workers);
}
catch (e) {
if (!(e instanceof _Break) && !(e instanceof _Continue))
throw e;
broken = true;
}
return { broken };
}
//# sourceMappingURL=concurrent.js.map