防抖(Debouncing)和节流(Throttling)是两种常见的性能优化手段,用于控制函数的执行频率,特别是在处理用户输入或其他频繁触发的事件时很有用。以下是用 JavaScript 实现防抖和节流函数的例子:
防抖函数(Debouncing)
防抖的思想是,在一定时间内,如果事件频繁触发,只执行最后一次。这样可以避免在短时间内多次触发事件导致函数被频繁调用。
function debounce(func, delay) {
let timerId;
return function (...args) {
clearTimeout(timerId);
timerId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
// 使用用例
const debounceFunction = debounce(() => {
console.log("Debounced function executed.");
}, 500);
// 调用 debounce 函数返回的函数,会在最后一次调用后延迟 500 毫秒执行
debouncedFunction();
节流函数(Throttling)
节流的思想是,在一定时间内,无论事件触发多少次,只执行一次。这样可以限制函数的执行频率,保证在规定时间内只执行一次。
function throttle(func, delay) {
let isThrottled = false;
return function (...args) {
if (!isThrottled) {
func.apply(this, args);
isThrottled = true;
setTimeout(() => {
isThrottled = false;
}, delay);
}
};
}
// 使用示例
const throttledFunction = throttle(() => {
console.log("Throttled function executed.")
}, 500)
// 调用 throttle 函数返回的函数,会在每 500 毫秒内执行一次
throttledFunction();
这是基本的实现,你可以根据需要进行调整。注意,这里的 func.apply(this, args) 调用了传入的原始函数,保留了原函数的上下文和参数。
不使用 setTimeout的 throttle
export const throttle = <T extends (...args: Parameters<T>) => ReturnType<T>>(
func: T,
delay: number
) => {
let lastCalled = 0;
return (...args: Parameters<T>): ReturnType<T> | undefined => {
const now = new Date().getTime();
if (now - lastCalled >= delay) {
lastCalled = now;
return func(...args);
}
};
};