UNPKG

@cloudize/async-interval

Version:

Modern version of setInterval for promises and async functions available in Node.js and browsers.

52 lines (51 loc) 1.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SetIntervalAsyncTimer = void 0; const MIN_INTERVAL_MS = 10; const MAX_INTERVAL_MS = 2147483647; class SetIntervalAsyncTimer { #timeout = undefined; #promise = undefined; #stopped = false; static startTimer(strategy, handler, intervalMs, ...handlerArgs) { intervalMs = Math.min(Math.max(Math.trunc(intervalMs), MIN_INTERVAL_MS), MAX_INTERVAL_MS); const timer = new SetIntervalAsyncTimer(); timer.#scheduleTimeout(strategy, handler, intervalMs, intervalMs, ...handlerArgs); return timer; } static async stopTimer(timer) { timer.#stopped = true; if (timer.#timeout) { clearTimeout(timer.#timeout); } if (timer.#promise) { await timer.#promise; } } #scheduleTimeout(strategy, handler, intervalMs, delayMs, ...handlerArgs) { this.#timeout = setTimeout(async () => { this.#timeout = undefined; this.#promise = this.#runHandlerAndScheduleTimeout(strategy, handler, intervalMs, ...handlerArgs); await this.#promise; this.#promise = undefined; }, delayMs); } async #runHandlerAndScheduleTimeout(strategy, handler, intervalMs, ...handlerArgs) { const startTimeMs = new Date().getTime(); try { await handler(...handlerArgs); } finally { if (!this.#stopped) { const executionTimeMs = new Date().getTime() - startTimeMs; const delayMs = strategy === "dynamic" ? intervalMs > executionTimeMs ? intervalMs - executionTimeMs : 0 : intervalMs; this.#scheduleTimeout(strategy, handler, intervalMs, delayMs, ...handlerArgs); } } } } exports.SetIntervalAsyncTimer = SetIntervalAsyncTimer;