typedash
Version:
modern, type-safe collection of utility functions
65 lines (64 loc) • 2.1 kB
JavaScript
//#region src/functions/throttle/throttle.ts
/**
* Creates a throttled function that limits the rate at which it can be called.
* @param func The function to be throttled.
* @param wait The number of milliseconds to wait between each invocation of the function.
* @param options The options for the throttling behavior.
* @param options.leading Whether to call the function on the leading edge of the timeout.
* @param options.trailing Whether to call the function on the trailing edge of the timeout.
* @returns The throttled function with `cancel` and `flush` methods.
*/
function throttle(func, wait = 0, options = {}) {
let timeoutId = null;
let lastArguments = null;
let lastContext = null;
let lastInvokeTime = 0;
const { leading = true, trailing = true } = options;
function invokeFunc(time) {
lastInvokeTime = time;
func.apply(lastContext, lastArguments ?? []);
lastContext = null;
lastArguments = null;
}
function trailingEdge() {
if (trailing && lastArguments) invokeFunc(Date.now());
timeoutId = null;
}
function timerExpired() {
const time = Date.now();
if (time - lastInvokeTime >= wait) trailingEdge();
else timeoutId = setTimeout(timerExpired, wait - (time - lastInvokeTime));
}
function throttledFunction(...args) {
const time = Date.now();
if (!lastInvokeTime && !leading) lastInvokeTime = time;
const remaining = wait - (time - lastInvokeTime);
lastArguments = args;
lastContext = this;
if (remaining <= 0 || remaining > wait) {
if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = null;
}
invokeFunc(time);
} else if (!timeoutId && trailing) timeoutId = setTimeout(timerExpired, remaining);
}
throttledFunction.cancel = () => {
if (timeoutId) clearTimeout(timeoutId);
lastInvokeTime = 0;
lastArguments = null;
lastContext = null;
timeoutId = null;
};
throttledFunction.flush = () => {
if (timeoutId) {
invokeFunc(Date.now());
clearTimeout(timeoutId);
timeoutId = null;
}
};
return throttledFunction;
}
//#endregion
export { throttle as t };
//# sourceMappingURL=throttle-BTbMIwUi.js.map