inSlices
uses setImmediate
Run steps in turn, letting other work run every slice milliseconds, so what a page or the warm-up makes in bulk
doesn't hold up the pages asked for meanwhile; in the background, it waits while a page is making something. It
stops when go says to; whether it finished.
import { pagesWorking } from "#codebase/tcmts/share"; export async function inSlices( steps: Iterable<() => unknown>, go: () => boolean = () => true, o: { slice?: number; background?: boolean } = {}, ): Promise<boolean> { const slice = o.slice ?? 10; if (!o.background) pagesWorking.n++; try { let since = performance.now(); for (const step of steps) { if (performance.now() - since > slice) { await new Promise((r) => setImmediate(r)); while (o.background && pagesWorking.n > 0) await new Promise((r) => setTimeout(r, 5)); if (!go()) return false; since = performance.now(); } step(); } return true; } finally { if (!o.background) pagesWorking.n--; } }