防抖和节流

75 阅读2分钟

防抖和节流,清晰解释,看这一篇就够啦

首先要区分一下什么是防抖?,什么是节流?

防抖

当事件触发时,相应的函数不会立即被执行,而是延迟一段时间再执行,并且在这个延迟时间内,如果又触发了,那就再推迟一段时间。什么效果呢?如果频繁的触发,只有最后一次是有效的。

应用场景

  • 搜索框搜索输入。只需用户最后一次输入完,再发送请求。
  • 窗口大小 resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。

如何实现呢?

  • 我们来整理一下思路,首先需要设置一个 Timeout 延时,在这个延时到达前,又被触发了,那么就重置一下这个 Timeout。那就是说不断的触发就会不断的重置,直到最后,长时间的停止。
// fn 会被防抖函数封装,返回一个真正的防抖函数
function debounce(fn, delay=500) {
    let timer = null;
    
    // 注意,返回的这个函数才是一个真正的防抖函数
    return function(...args) {
        const context = this;
        
        // 重复触发时,重置计时器
        if (timer !== null) {
            clearTimeout(timer);
        }
        
        // 根据 delay 设置延时
        timer = setTimeout(() => {
            fn.apply(context, args)
        }, delay)
    }
}

节流

在规定的一段时间内,相应的函数只会被触发一次,即使在这段时间内频繁的触发,也只会有一次生效。

应用场景

  • 滚动加载,加载更多或滚到底部监听。
  • 搜索框,搜索联想功能。

如何实现呢?

function throttled(fn, delay) {
    let timer = null;
    
    let last = Date.now();
    return function() {
        let now = Date.now();
        let remaining = delay - (now - last);
        
        const context = this;
        const args = arguments;
        
        clearTimeout(timer);
        // 没到规定的时间间隔会一直重置
        if (remaining > 0) {
           timer = setTimeout(fn, delay);
        } else {
            last = Date.now();
            fn.apply(context, args);
        }
    }
}