UNPKG

@nesvet/n

Version:
107 lines 3.33 kB
import { noop } from "./noop.js"; import { StatefulPromise } from "./StatefulPromise.js"; export function debounce(callback, limit = 0, options = {}) { let { leading = false, trailing = true } = options; const { maxWait = Infinity } = options; let timeout; let maxWaitTimeout; let end; let context; let args; let initial; let final; let result; const expired = async () => { const n = Date.now(); if (n >= end) { timeout = undefined; end = undefined; clearTimeout(maxWaitTimeout); maxWaitTimeout = undefined; if (typeof final == "function") await final(); debounced.resolve(result); initial = leading; } else { clearTimeout(timeout); timeout = setTimeout(expired, end - n); } }; const maxWaitExpired = Number.isFinite(maxWait) ? () => { if (final === run) final = false; run(); maxWaitTimeout = setTimeout(maxWaitExpired, maxWait); } : null; async function run() { try { result = await callback.apply(context, args); return result; } catch (error) { debounced.reject(error); throw error; } } if (leading && typeof leading == "boolean") leading = run; initial = leading; if (trailing && typeof trailing == "boolean") trailing = run; final = trailing; const debounced = Object.assign(function (..._args) { args = _args; context = this; // eslint-disable-line no-invalid-this end = Date.now() + limit; final = trailing; if (!debounced.promise.isPending) debounced.promise = new StatefulPromise((resolve, reject) => { debounced.resolve = resolve; debounced.reject = reject; if (typeof initial == "function") { initial(); initial = false; if (final === run) final = false; } if (!timeout) { timeout = setTimeout(expired, limit); if (maxWaitExpired) maxWaitTimeout = setTimeout(maxWaitExpired, maxWait); } }); return debounced.promise; }, { callback, promise: StatefulPromise.resolved(undefined), resolve: noop, reject: noop, run, clear: async (shouldRun) => { clearTimeout(timeout); timeout = undefined; clearTimeout(maxWaitTimeout); maxWaitTimeout = undefined; debounced.resolve(shouldRun ? await run() : result); } }); return debounced; } debounce.noop = Object.assign(() => { }, { callback: noop, promise: StatefulPromise.resolved(undefined), // eslint-disable-line unicorn/no-useless-undefined resolve: noop, reject: noop, run: noop, clear: noop }); export function throttle(callback, limit, options) { return debounce(callback, limit, { maxWait: limit, leading: true, trailing: true, ...options }); } //# sourceMappingURL=debounce.js.map