防抖与节流


防抖函数:
规定函数至少间隔多久执行。

函数执行过一次后,在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


文章作者: DreamHeaven
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 DreamHeaven !
  目录