防抖和节流

什么是防抖(Debounce)?

短时间内连续触发多次事件(用户点击/鼠标移动/键盘事件/鼠标滚轮等),只执行最后一次
在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

      var btn = document.getElementById("btn");
      btn.onclick = debounce(() => {
        console.log("防抖执行了");
      }, 1000);
      
      //封装防抖函数(debounce)
      function debounce(fn, wait) {
        let timer = null;
        return function () {
          let _this = this;
          let args = arguments;
          // 每次点击时都是先关在开,永远保证当前只有一个正在执行的定时器
          if (timer) {
            clearTimeout(timer);
          }
          timer = setTimeout(function () {
            fn.apply(_this, args);
          }, wait);
          console.log(timer); 
        };
      }

下图是控制台的输出情况:

防抖和节流

可以发现,只有当用户停止点击后,才会触发fn()函数,打印“防抖执行了”语句,每次产生新的触发,都会覆盖旧有触发的定时器,并重新计时,即多次点击只有计最后一次有效

什么是节流(Throttle)?

在一个单位时间内,连续多次事件触发,只执行第一次。短时间内连续触发多次事件,会减少执行次数。达到稀释函数执行频率的效果。
可以将节流函数看作一个闸门,一旦有事件触发,就立即关闭闸门,不让其他事件进入,直到进入的事件响应结束,才再次开放闸门。

1.用定时器实现:

      var btn = document.getElementById("btn"); 
      btn.onclick = throttle(() => { console.log("节流函数执行"); }, 1000);
      
      function throttle(fn, wait) {
        let timer = null;
        return function () {
          let _this = this;
          let _args = arguments;

          if (!timer) {   //若当前没有正在执行的定时器
            timer = setTimeout(function () {
              timer = null;
              fn.apply(_this, _args);
            }, wait); //只有当定时器将wait时间走完,timer才会再次被赋值null,才可再次进入if语句
          }
          console.log(timer);
        };
      }

2.用时间戳实现

     function throttle1(fn, wait) {
        let time = 0;
        return function () {
          let _this = this;
          let _args = arguments;
          
          let now = Date.now();
          //相邻两次点击的时间间隔大于需要wait的时间,即上一单位时间内事件已响应完毕
          if (now - time > wait) { 
            fn.apply(_this, _args);
            time = now;
          }
        };

下图是控制台的输出情况:

防抖和节流

可以发现,与防抖函数不同,当用户多次点击时,实际响应的始终是第一次点击时的定时器。只至定时器将需要wait的时间走完,打印了”节流函数执行”。即单位时间内,多次触发仅执行第一次。

防抖和节流的异同

相同点:

  1. 作用都是为了降低回调函数触发频率,减小计算负担。
  2. 都是基于一次性定时器setTimeout实现的,并运用闭包进行封装。

区别:

防抖函数多次触发只执行最后一次,节流函数多次触发只执行第一次。

触发频率不同,实际上防抖函数比节流函数更为“严格”,防抖在单位时间s内永远只执行最后一次,而节流函数函数则可执行s/wait(向下取整)次。

例如,防抖和节流函数定时器的wait时间均为500ms,那么在5s内,防抖函数仅触发最后一次,而节流函数将触发10次。

防抖和节流的使用场景

防抖(适合仅需一次生效的场景)

  1. 登录,发送验证码,限时秒杀等按钮,用户短时间内多次点击,仅最后一次响应并发送请求
  2. search搜索时,等待用户结束输入后,再发送请求。
  3. windows触发resize时,会频繁进行计算调整窗口大小,用防抖节约计算资源。

节流(适合隔一段时间执行一次场景)

  1. 滚动监听,例如下拉加载,触底加载等
  2. 搜索框的搜索联想功能

原文链接:https://juejin.cn/post/7344002850320318504 作者:Lytir

(0)
上一篇 2024年3月9日 上午10:37
下一篇 2024年3月9日 上午10:48

相关推荐

发表回复

登录后才能评论