throttle
function
Creates a throttled function that only invokes func at most once per every wait milliseconds.
Installation
Import
import { throttle } from '@tulx/utils';Source Code
Implementation
/**
* Creates a throttled function that only invokes func at most once per every wait milliseconds.
*
* @param func - The function to throttle.
* @param wait - The number of milliseconds to throttle invocations to.
* @param options - The options object.
* @returns Returns the new throttled function.
*
* @example
* ```ts
* const throttled = throttle(() => console.log('hello'), 1000);
* throttled(); // Will log 'hello' immediately
* throttled(); // Ignored
* ```
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function throttle<T extends (...args: any[]) => any>(
func: T,
wait: number = 0,
options?: {
leading?: boolean;
trailing?: boolean;
}
): (...args: Parameters<T>) => void {
let timeoutId: ReturnType<typeof setTimeout> | undefined;
let lastInvokeTime = 0;
const leading = options?.leading !== false;
const trailing = options?.trailing !== false;
function invokeFunc(this: unknown, args: Parameters<T>, time: number): void {
lastInvokeTime = time;
func.apply(this, args);
}
function leadingEdge(this: unknown, time: number, args: Parameters<T>): void {
if (leading) {
invokeFunc.apply(this, [args, time]);
}
lastInvokeTime = time;
}
function remainingWait(time: number): number {
const timeSinceLastInvoke = time - lastInvokeTime;
return wait - timeSinceLastInvoke;
}
function shouldInvoke(time: number): boolean {
return lastInvokeTime === 0 || time - lastInvokeTime >= wait;
}
function timerExpired(this: unknown, args: Parameters<T>): void {
const time = Date.now();
if (trailing && shouldInvoke(time)) {
invokeFunc.apply(this, [args, time]);
}
timeoutId = undefined;
}
function cancel(): void {
if (timeoutId !== undefined) {
clearTimeout(timeoutId);
}
lastInvokeTime = 0;
timeoutId = undefined;
}
function throttled(this: unknown, ...args: Parameters<T>): void {
const time = Date.now();
if (shouldInvoke(time)) {
if (timeoutId === undefined) {
leadingEdge.apply(this, [time, args]);
}
timeoutId = setTimeout(() => timerExpired.apply(this, [args]), wait);
} else if (timeoutId === undefined && trailing) {
timeoutId = setTimeout(
() => timerExpired.apply(this, [args]),
remainingWait(time)
);
}
}
throttled.cancel = cancel;
return throttled;
}
Example
import { throttle } from '@tulx/utils';
const throttled = throttle(() => console.log('hello'), 1000);
throttled(); // Will log 'hello' immediately
throttled(); // IgnoredRelated Functions
after
The opposite of before; this method creates a function that invokes func once it's called n or more times.
ary
Creates a function that invokes func, with up to n arguments, ignoring any additional arguments.
before
Creates a function that invokes func, with the this binding and arguments of the created function, while it's called less than n times.
bind
Creates a function that invokes func with the this binding of thisArg and partials prepended to the arguments it receives.
bindKey
Creates a function that invokes the method at object[key] with partials prepended to the arguments it receives.
curry
Creates a function that accepts arguments of func and either invokes func returning its result, or returns a function that accepts the remaining arguments.