防抖函数:
规定函数至少间隔多久执行。
函数执行过一次后,在n秒内不能再次执行,否则推迟函数执行
下一次函数调用将清除上一次的定时器,并用setTimeout重新计时
/**
* @description: 防抖函数
* @param {Function} func 回调函数
* @param {Number} wait 等待时间 ms
* @param {Boolean} immediate 是否立即执行
* @return: result func返回的结果
*/
public static debounce(func: Function, wait: number = 100, immediate: boolean = false) {
let timeoutID: number = 0, result: any;
let debounced: FunDebounceOrThrottle = function () {
clearTimeout(timeoutID);
let arg = arguments;
if (immediate) {
if (!timeoutID) result = func.apply(func, arg);
timeoutID = setTimeout(() => {
timeoutID = 0;
}, wait);
} else {
timeoutID = setTimeout(() => {
func.apply(func, arg);
}, wait);
}
return result;
};
// 取消防抖
debounced.cancel = function () {
clearTimeout(timeoutID);
timeoutID = 0;
};
return debounced;
}
节流函数:
规定函数在某时间段内最多执行一次
函数在n秒内最多执行一次
下一次函数调用将清除上一次的定时器
若函数执行的时间间隔小于等于规定时间间隔则用setTimeout在规定时间后再执行
若函数执行的时间间隔大于规定时间间隔则执行函数,并重新计时
/**
* @description: 节流函数
* @param {Function} func 回调函数
* @param {Number} wait 等待时间 ms
* @param {Object} options leading代表是否开头执行,tailing代表是否结尾执行
* @return: null
*/
public static throttle(func: Function, wait: number, options: IThrottleOptions = {leading: true, trailing: true}) {
let timeoutID: number = 0;
let previous = 0;
let throttled: FunDebounceOrThrottle = function () {
let now = new Date().getTime();
if (!previous && !options.leading) previous = now;
let remaining = wait - (now - previous);
let arg = arguments;
if (remaining <= 0 || remaining > wait) {
if (timeoutID) {
clearTimeout(timeoutID);
timeoutID = 0;
}
previous = now;
func.apply(func, arg);
} else if (!timeoutID && options.trailing) {
timeoutID = window.setTimeout(() => {
previous = !options.leading ? 0 : new Date().getTime();
timeoutID = 0;
func.apply(func, arg);
}, remaining);
}
};
// 取消节流
throttled.cancel = function () {
clearTimeout(timeoutID);
previous = 0;
timeoutID = 0;
};
return throttled;
}
}
函数防抖与函数节流的对比
首先明确一点:不管是函数节流还是函数防抖,我们减少的是事件处理程序的调用频率(上面列子的realFunc函数),而不是事件的调用频率。每次滚动、每次输入都会触发事件。
函数防抖和函数节流都用了闭包封装
何时使用函数防抖、何时使用函数节流看需求:
当我们只需要处理最后一次触发事件时,用函数防抖。如窗口大小值变化时并不需要计算中间变化的过程,只需要窗口大小改变完成后的值
当事件触发过于频繁,我们需要限制事件处理程序的调用频率时,用函数节流。
链接:https://blog.csdn.net/qq_37860930/article/details/83505547