lodash 防抖和限流

阅读更多
去抖 和 节流

debounce 和 throttle 的相同点:setTimeout

debounce 和 throttle 的不同点:

debounce 有一个等待时长,如果在这个等待时长内,再次调用了函数,就取消上一个定时器,并新建一个定时器。所以 debounce 适用于 input, keyup, keydown 等事件, 亦或者 click 事件需要防止用户在某个时间范围内多次点击的时候,也可以用。注:在lodash 的实现中 中并没有取消新建定时器的做法,是用时间来判断的。


throttle 也有一个等待时长,每隔一段这个等待时长,函数必须执行一次。如果在这个等待时长内,当前延迟执行没有完成,它会忽略接下来调用该函数的请求,不会去取消上一个定时器。所以 throttle 适用于 scroll, mousemove 等事件。在lodash 的实现中,还有一个等待的最大时长,这个我们分析源码时再讨论。


resize 事件,使用 debounce 或 throttle 都行,看你的需求啦。

举个栗子,使用 lodash 处理 resize 事件时,在 wait 参数不是非常小的情况下:
用debounce的话,会在用户停止改变浏览器窗口大小时触发,也就是只是在最后触发一次。
用throttle的话,会在用户改变浏览器窗口大小的过程中,每隔一段时间触发一次。

function debounce(fn, wait) {
    let callback = fn;    
    let timerId = null;

    function debounced() {
        // 保存作用域
        let context = this;
        // 保存参数,例如 event 对象
        let args = arguments;        

        clearTimeout(timerId);        
        timerId = setTimeout(function() {            
            callback.apply(context, args);
        }, wait);
    }
    
    // 返回一个闭包
    return debounced;         
}

// test
let resizeFun = function(e) {
    console.log('resize');
};
window.addEventListener('resize', debounce(resizeFun, 500));


throttle 相对于 debounce 的最大区别就是它不会取消上一次函数的执行。
所以我们可以基于 debounce 去调整一下。

function throttle(fn, wait) {
    let callback = fn;    
    let timerId = null;

    // 是否是第一次执行
    let firstInvoke = true;

    function throttled() {
        let context = this;
        let args = arguments;           

        // 如果是第一次触发,直接执行
        if (firstInvoke) {
            callback.apply(context, args);
            firstInvoke = false;
            return ;
        }

        // 如果定时器已存在,直接返回。        
        if (timerId) {
            return ;
        }

        timerId = setTimeout(function() {  
            // 注意这里 将 clearTimeout 放到 内部来执行了
            clearTimeout(timerId);
            timerId = null;

            callback.apply(context, args);
        }, wait);
    }

    // 返回一个闭包
    return throttled;
}

// test
let resizeFun = function(e) {
    console.log('resize');
};
window.addEventListener('resize', throttle(resizeFun, 500));


转载出自 :https://juejin.im/post/5c39616de51d45783b4adf6d


你可能感兴趣的:(JavaScript,UI)