func-utils.ts•2.46 kB
/**
* Creates a debounced function that delays invoking func until after wait milliseconds
* @param func Function to debounce
* @param wait Wait time in milliseconds
*/
export function debounce<T extends (...args: any[]) => any>(
func: T,
wait: number
): (...args: Parameters<T>) => void {
let timeout: NodeJS.Timeout | null = null;
return function(...args: Parameters<T>): void {
const later = () => {
timeout = null;
func(...args);
};
if (timeout !== null) {
clearTimeout(timeout);
}
timeout = setTimeout(later, wait);
};
}
/**
* Creates a throttled function that only invokes func at most once per wait period
* @param func Function to throttle
* @param wait Wait time in milliseconds
*/
export function throttle<T extends (...args: any[]) => any>(
func: T,
wait: number
): (...args: Parameters<T>) => void {
let timeout: NodeJS.Timeout | null = null;
let lastArgs: Parameters<T> | null = null;
let lastCallTime = 0;
return function(...args: Parameters<T>): void {
const now = Date.now();
const timeSinceLastCall = now - lastCallTime;
lastArgs = args;
if (timeSinceLastCall >= wait) {
lastCallTime = now;
func(...args);
} else if (timeout === null) {
timeout = setTimeout(() => {
lastCallTime = Date.now();
timeout = null;
if (lastArgs !== null) {
func(...lastArgs);
}
}, wait - timeSinceLastCall);
}
};
}
/**
* Creates a function that is only called once
* @param func Function to call once
*/
export function once<T extends (...args: any[]) => any>(
func: T
): (...args: Parameters<T>) => ReturnType<T> {
let called = false;
let result: ReturnType<T>;
return function(...args: Parameters<T>): ReturnType<T> {
if (!called) {
called = true;
result = func(...args);
}
return result;
};
}
/**
* Creates a memoized function that caches results
* @param func Function to memoize
*/
export function memoize<T extends (...args: any[]) => any>(
func: T
): (...args: Parameters<T>) => ReturnType<T> {
const cache = new Map<string, ReturnType<T>>();
return function(...args: Parameters<T>): ReturnType<T> {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key) as ReturnType<T>;
}
const result = func(...args);
cache.set(key, result);
return result;
};
}