Skip to content

Instantly share code, notes, and snippets.

@oleggrishechkin
Created January 7, 2024 23:38
Show Gist options
  • Save oleggrishechkin/aa6023891d546fce589b29ca9d538985 to your computer and use it in GitHub Desktop.
Save oleggrishechkin/aa6023891d546fce589b29ca9d538985 to your computer and use it in GitHub Desktop.
Debounce + Throttle decorator
export const debounceThrottle = <T extends any[]>(func: (...args: T) => any, { debounce = 0, throttle = 0 } = {}) => {
let debounceId: any = null;
let throttleId: any = null;
let lastArgs: T | null = null;
const run = () => {
const argsToCall = lastArgs;
lastArgs = null;
if (argsToCall) {
func(...argsToCall);
}
};
const clearDebounce = () => {
if (debounceId) {
clearTimeout(debounceId);
debounceId = null;
}
};
const clearThrottle = () => {
if (throttleId) {
clearTimeout(throttleId);
throttleId = null;
}
};
const decoratedFunc = (...args: T) => {
lastArgs = args;
clearDebounce();
if (debounce) {
debounceId = setTimeout(() => {
clearThrottle();
debounceId = null;
run();
}, debounce);
}
if (throttle && !throttleId) {
throttleId = setTimeout(() => {
clearDebounce();
throttleId = null;
run();
}, throttle);
}
};
const force = () => {
clearDebounce();
clearThrottle();
run();
};
const clear = () => {
clearDebounce();
clearThrottle();
lastArgs = null;
};
decoratedFunc.force = force;
decoratedFunc.cancel = clear;
return Object.assign(decoratedFunc, {
force,
clear,
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment