不说话,装高手。
Maintain silence and pretend to be an experta
防抖和节流本质上都是 Javascript 中常用的两种性能优化方式。他们的作用是减少函数的执行次数,以提高代码性能
如上图所示,如果不使用防抖节流函数正常执行,则会一直触发函数。这对性能有很大的影响,当使用 防抖(Debounce) 来执行函数,在指定时间间隔内,方法会将前面触发的函数过滤,只执行最后一次触发的函数,使用 节流(Throttle) 来执行函数,在指定时间间隔内无论触发多少次函数,都只执行第一次触发的函数。
防抖和节流在不同的应用场景中展现出其重要性。防抖适用于需要等待用户操作完成或者停顿后才进行相应处理的情况,如搜索框实时搜索和窗口大小调整。节流则适用于需要限制事件触发频率的情况,如页面滚动加载和按钮点击。根据具体需求,选择合适的技术可以优化用户体验、减少不必要的资源消耗,从而提升前端应用的性能。
/**
* 防抖函数
* @param {Function} func 要执行的函数
* @param {Number} wait 延迟执行毫秒数
* @param {Boolean} immediate 是否立即执行
*/
const debounce = <T extends (...args: any[]) => void>(func: T, wait: number, immediate = false) => {
let timer: NodeJS.Timeout;
// later 函数用于设置延时执行 func
const later = function (this: any, ...args: any[]) {
timer = setTimeout(() => {
// 如果不是立即执行模式,则调用原始函数 func
if (!immediate) {
func.apply(this, args);
}
}, wait);
};
// 返回一个函数,用于包装原始函数 func
return function (this: any, ...args: any[]) {
const context = this;
// 是否立即执行的判断条件
const callNow = immediate && !timer;
clearTimeout(timer);
// 如果满足立即执行条件,则立即执行 func
if (callNow) {
func.apply(context, args);
}
// 延时执行 func
later.apply(context, args);
} as T;
};
// 300ms内只执行最后一次触发的函数
const debouncedFunction = debounce((value: string) => {
console.log(value);
}, 300);
debouncedFunction('1');
debouncedFunction('2');
debouncedFunction('3');
setTimeout(function() {
debouncedFunction('4');
debouncedFunction('5');
}, 400)
// 结果
console.log(3);
console.log(5);
/**
* 节流函数
* @param {Function} func 要执行的函数
* @param {Number} wait 延迟执行毫秒数
* @param {Boolean} immediate 是否立即执行
*/
const throttle = <T extends (...args: any[]) => void>(func: T, wait: number, immediate: boolean = false): T => {
// 定义一个标志变量,表示是否处于节流状态
let inThrottle: boolean = false;
// 返回一个函数,该函数将被用作节流后的函数
return function (this: any, ...args: any[]) {
const context = this;
if (!inThrottle) {
// 如果需要立即执行,则执行原始函数并进入节流状态
if (immediate) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => {
inThrottle = false;
}, wait);
} else {
// 如果不需要立即执行,同样执行原始函数并进入节流状态
func.apply(context, args);
inThrottle = true;
// 在指定的等待时间后,解除节流状态
setTimeout(() => {
inThrottle = false;
}, wait);
}
}
} as T;
}
const throttledFunction = throttle((value: string) => {
console.log(value);
}, 300, true);
throttledFunction('1');
throttledFunction('2');
throttledFunction('3');
setTimeout(function() {
throttledFunction('4');
throttledFunction('5');
}, 400)
// 结果
console.log(1);
console.log(4);