Something went wrong. Try again.
Mirrored from GitHub github.com/roostorg/coop
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162import { delay } from './utils.js';
/** * Stores/runs a set of timers and can alert callers when all timers * have finished, and that can be closed by callers. */export default class TimerSet { // We have to actually store the timers (eek), // not just a count, to support close functionality. private readonly timers: Set<any> = new Set(); private closed = false;
public setTimeout( cb: (...args: any[]) => void, ms: number, ...args: any[] ): NodeJS.Timeout { if (this.closed) { throw new Error('TimerSet is closed. New timers cannot be added.'); }
const timer = setTimeout(() => { this.timers.delete(timer); cb(...args); }, ms);
this.timers.add(timer); return timer; }
public clearTimeout(timeout: NodeJS.Timeout) { this.timers.delete(timeout); clearTimeout(timeout); }
/** * Stops the set from accepting more timers and returns a promise that * resolves when all known timers are done. If `timeout` ms elapse before * the timers finish, it `unref`s them so they don't block the node process * from closing, and then its returned promise resolves. */ public async close(timeout?: number) { this.closed = true;
// Ironic to use a timer to poll a count of timers, but hey. const timersDone = async (): Promise<void> => this.timers.size === 0 ? undefined : delay(20).then(timersDone);
if (timeout === undefined) { return timersDone(); }
const unrefAllAfterTimeout = delay(timeout).then(() => { this.timers.forEach((it) => { it.unref(); }); });
await Promise.race([unrefAllAfterTimeout, timersDone()]); }}