节流防抖原理分析及实现

406 阅读1分钟

防抖

将高频操作放在最后一次执行, 常用场景用户输入

节流

每隔一段时间执行一次函数, 常用场景滚动条事件, resize事件

上代码

<html>
  <button id="button">
    点击
  </button>
  <script>
    document.querySelector('button').addEventListener('click',debounce(click,3000,true))  // 验证防抖
    document
      .querySelector("button")
      .addEventListener("click", throttle(click, 1000));  // 验证节流
    function click() {
      console.log(1);
    }
    
    // 防抖
    // 如果存在定时器, 就清空
    function debounce(fn, wait, immediate) {
      let timer = null; 
      // 闭包 存储私有变量timer 每次进入函数前,都是使用当前的timer做判断
      return function() {
        if (immediate && !timer) {
          fn.apply(this, arguments);
        }
        if (timer) {
          clearTimeout(timer);
        }
        timer = setTimeout(() => {
          fn.apply(this, arguments);
        }, wait);
      };
    }
    // 节流
    // 定时器时间走完后, 清空定时器
    function throttle(fn, wait) {
      let timer = null;
      // 闭包 存储私有变量timer
      return function() {
        // 定时器不存在才能添加定时器
        if (!timer) {
          timer = setTimeout(() => {
            fn.apply(this, arguments);
            timer = null;
          }, wait);
        }
      };
    }
  </script>
</html>

终极区别,

  • 防抖在定时器外清除定时器, 只要操作未执行完, 就不进入定时器执行
  • 节流在定期器内清除定时器, 只要定时器未跑完, 就不清空定时器