UNPKG

@stnekroman/tstools

Version:

Set of handy tools for TypeScript development

82 lines (68 loc) 2.88 kB
import {Functions} from "../Functions"; /** * Ported patterns from http://unscriptable.com/2009/03/20/debouncing-javascript-methods/ */ export namespace Throttle { export interface ThrottleFunction<ARGS extends unknown[] = void[]> extends Functions.ArgsFunction<ARGS, void> { cancel(): void; // cancels and discards any pending calls, but continues to serve new incoming calls } /** * Returns function, which will remember call arguments from it's last invocation, * and will fire given callback after specified timeout with previously collected arguments. * @param callback to be called, throttled by timeout * @param timeout in milliseconds */ export function throttle<ARGS extends unknown[] = void[]>(callback: Functions.ArgsFunction<ARGS, void>, timeout: number ): ThrottleFunction<ARGS> { let lastArgs : ARGS | undefined; let timerId : NodeJS.Timeout | number | undefined; const throttleFunction: ThrottleFunction<ARGS> = (...args: ARGS): void => { lastArgs = args; if (timerId === undefined) { timerId = setTimeout((): void => { callback(...lastArgs!); lastArgs = undefined; timerId = undefined; }, timeout); } }; throttleFunction.cancel = (): void => { if (timerId !== undefined) { clearTimeout(timerId); timerId = undefined; } lastArgs = undefined; }; return throttleFunction; } /** * Returns functions, which will remember arguments from it's last call and (re)schedule given callback to fire (with last arguments) * after last function call with specified timeout. New function call delays actual callback further. * @param callback to call after timeout * @param timeout in milliseconds */ export function deferring<ARGS extends unknown[] = void[]>(callback: Functions.ArgsFunction<ARGS, void>, timeout: number): ThrottleFunction<ARGS> { let lastArgs: ARGS | undefined; let timerId: NodeJS.Timeout | number | undefined; const throttleFunction: ThrottleFunction<ARGS> = (...args: ARGS): void => { lastArgs = args; if (timerId !== undefined) { clearTimeout(timerId); } timerId = setTimeout((): void => { callback(...lastArgs!); lastArgs = undefined; timerId = undefined; }, timeout); }; throttleFunction.cancel = (): void => { if (timerId !== undefined) { clearTimeout(timerId); timerId = undefined; } lastArgs = undefined; }; return throttleFunction; } }