简述防抖和节流,以及如何实现

防抖(debounce)和节流(throttle)

本质都是为了控制函数在高频事件下的触发次数,降低函数执行频率,节省计算资源,提高性能。不然的话,会容易造成网络阻塞,页面卡顿,或者数据错乱覆盖等情况。

两者区别:

防抖:

   高频事件下,控制执行最后一次

节流:

高频事件下,控制(函数)执行的次数。也就是一个单位时间内,只允许执行1次。


实现一个简单的防抖:

<body>
    <input type="text" />

    <script>
      let inp = document.querySelector("input");

      // 防抖  debounce(callback,delay);
      inp.oninput = debounce(function () {
        // 在这里可以进行逻辑操作
        console.log(this.value);
        ...
      }, 2000);

      // 通过闭包实现防抖
      function debounce(fn, delay) {
        let timer = null;
        return function () {
          if (timer !== null) {
            clearTimeout(timer);
          }

          timer = setTimeout(() => {
             // 箭头函数没有自己的this,改变指向,使其指向input。同时执行fn函数
            fn.call(this);
          }, delay);
        };
      }
    </script>
  </body>

案例分析:

         第一次点击了输入框,输入内容后,开启定时器,timer会得到一个值。(这个值代表着等待队列);

        第二次输入内容时,会进入if判断(已经有值,不为null)。执行清除定时器。重新生成一个定时器,timer得到一个新的值;

        如果在3秒内,不停的输入内容,则会不停地触发事件——清除上一个定时器,开启新的定时器;

         直到最后一次输入结束,最后一个定时器等待3秒后,输出结果。

可以看出,防抖的关键点在于:利用闭包,在返回的函数体里,通过不断开启和清除定时器,在限定时间内不断点击,仍然只执行最后一次


实现简单版的节流:

        第一种方式:通过时间戳实现             

            间隔时间 wait

            初始时间 start-time

            最新时间 new-time (事件被触发时计算)

            当2者时间差 < wait , 不能执行事件函数

            当2者时间差 > = wait , 执行操作

        案例分析

<style>
     body {
       height: 2000px;
     }
</style>

<script>
     window.onscroll = function (e) {
        test();
     };

     // 执行节流函数
     let test = throttle(function () {
        // 在这里进行逻辑操作
        console.log("hello");
     }, 2000)

     // 节流
     function throttle(fn, wait) {
        // 获取初始时间
        let start = 0;

        return function () {
          let now = new Date().getTime();
          // 判断前后时间戳的差值
          if (now - start < wait) return;
          fn();
          // 重新设置初始时间
          start = now;
        };
      }
</script>

第二种方式: 通过控制锁的状态,实现节流

 <script>
      window.onscroll = throttle(function () {
        console.log("hello world");
      }, 3000);

      // 通过定时器实现节流
      function throttle(fn, wait) {
        let lock = true;
        return function () {
          if (lock) {
            // 关锁
            lock = false;
            // 通过定时器开锁
            setTimeout(() => {
              lock = true;;
              fn();
            }, wait);
          }
        };
      }
       
</script>

第一次,lock=true ,进入if判断,关锁---等待3秒,开锁,执行操作;

第二次,lock=true ,进入判断,关锁---等待3秒,开锁,重复操作...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值