Throttle and Debounce (in Typescript)
Throttle
Throttling ensures that the function is called at a regular interval, suppressing excessive calls and reducing the overall number of function invocations.
- Basically, used for rate-limiting.
Example: In a scroll event handler, you might want to update the UI or trigger certain actions at a controlled rate to prevent excessive updates and improve performance.
type ThrottledFunction<T extends (...args: any[]) => any> = {
(this: ThisParameterType<T>, ...args: Parameters<T>): void;
cancel: () => void;
};
function throttle<T extends (...args: any[]) => any>(
func: T,
delay: number
): ThrottledFunction<T> {
let lastCall = 0;
let timeout: NodeJS.Timeout | null = null;
const throttledFunc: ThrottledFunction<T> = function (
this: ThisParameterType<T>,
...args: Parameters<T>
) {
const now = Date.now();
if (now - lastCall >= delay) {
func.apply(this, args);
lastCall = now;
} else {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
func.apply(this, args);
lastCall = Date.now();
timeout = null;
}, delay - (now - lastCall));
}
};
throttledFunc.cancel = function () {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
};
return throttledFunc;
}
Example usage:
function handleScroll(event: Event) {
console.log('Scrolled');
}
const throttledScroll = throttle(handleScroll, 100);
window.addEventListener('scroll', throttledScroll);
// To cancel the throttled function:
// throttledScroll.cancel();
Debounce
Debouncing is a technique where a function call is delayed until a certain amount of time has passed since the last invocation. If the function is called again within that time period, the timer is reset, and the function call is postponed again.
- Basically, used for delaying.
Example: In an autocomplete search field, you may want to wait for the user to finish typing before making a request to fetch suggestions.
function debounce<T extends (...args: any[]) => void>(
func: T,
delay: number
): (...args: Parameters<T>) => void {
let timeoutId: NodeJS.Timeout;
return (...args: Parameters<T>) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func(...args);
}, delay);
};
}
Example usage:
function search(query: string) {
// Perform search operation
console.log(`Searching for "${query}"...`);
}
const debouncedSearch = debounce(search, 300);
// Call the debounced function
debouncedSearch("keyword");
debouncedSearch("another keyword");
debouncedSearch("third keyword");