弄懂防抖与节流很容易

154 阅读2分钟

防抖与节流在前端开发中运用较多,同时也是面试问的比较多的问题。下面主要从为什么需要防抖与节流防抖与节流的具体含义防抖与节流的区别防抖与节流的使用场景模拟这四个方面阐述。

为什么需要防抖与节流

当用户以非常人一般的速度操作触发时,浏览器可能会出现卡顿的现象,或者用户频繁提交导致频繁调用同一个接口,故为了避免极大的浪费资源以及降低性能,就有必要采取防抖或节流的方法来解决。

防抖与节流的具体含义

防抖:前面的所有触发都被取消,最后一次执行在规定时间之后才会触发,也就是说如果连续快速的触发,只会执行一次。

重点:在连续快速的触发后,只执行一次

节流:在规定的间隔时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调,把频繁触发变为少量触发

重点:将频繁触发变为少量触发,旨在“节约”

看着这一对我想到了setTimeout()和setInterval()这一对。

防抖与节流的区别

从防抖与节流的含义上来看,两者的区别从响应次数上有了明显的差别。

1.当用户频繁调用同一个接口时,可以使用防抖,最终只调用一次,提高性能。

2.当用户触发速度过快,提供该回调函数计算的时间较短,可能浏览器会出现卡顿现象,那么就可以使用节流,将频繁的触发变为少量的触发。

防抖与节流的使用场景模拟

1.防抖

1.1没有使用防抖

主要代码:

<body>
  <span>请输入需要查找的内容:</span><input type="text" />

  <script>
    let input=document.querySelector('input')
    input.oninput=function(){
      console.log('调用了接口')
    }
  </script>
</body>

没有使用防抖显示的结果:

image.png

可以看出只要在搜索框中输入一次就会调用一次接口,但是一般都是等输入完后才调用接口更好,故需要引入防抖。

这里使用插件lodash来实现,具体操作见:www.lodashjs.com/docs/lodash…

1.2使用防抖

使用防抖后代码:

<body>
  <span>请输入需要查找的内容:</span><input type="text" />
  
  //引入lodash.js
  <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.js"></script>
  <script>
    let input=document.querySelector('input')
    input.oninput= _.debounce(function(){
      console.log('调用了接口')
    },1000)
  </script>
</body>

使用防抖后的结果:

image.png

在连续的输入后,最后一次输入完毕后的一秒钟,才调用一次接口。

2.节流

2.1没有使用节流

主要代码:

<body>
  统计的数为:<span>0</span><br/>
  <button>+1</button>
  
  <script>
    let count=0
    let btn=document.querySelector('button')
    let span=document.querySelector('span')
    btn.onclick=function(){
      count++
      console.log(`点击了${count}次`)
      span.innerHTML=parseInt(span.innerHTML)+1
      console.log(span.innerHTML)
    }
  </script>
</body>

没有使用节流的效果:

image.png

当以很快的速度点击button按钮时,即频繁触发,正常情况下频繁点击了多少次就会执行多少次,在前面也分析过,这样会导致很多问题,故需要使用节流来解决。

同样是使用插件lodash来实现,具体操作见:www.lodashjs.com/docs/lodash…

2.2使用节流

使用节流后的代码:

<body>
  统计的数为:<span>0</span><br/>
  <button>+1</button>

  <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.js"></script>
  <script>
    let count=0
    let btn=document.querySelector('button')
    let span=document.querySelector('span')
    // 该段代码只是为了效果更加的清晰,没有节流
    btn.addEventListener('click', function () {
        count++
        console.log(`点击了${count}次`)
      })
    // 使用了节流
    btn.addEventListener('click', _.throttle(function () {
        span.innerHTML = parseInt(span.innerHTML) + 1
        console.log(span.innerHTML)
      }, 1000))
  </script>
</body>

使用节流后的显示效果:

image.png

不管多么频繁的触发,它都会在规定的时间一秒间隔响应,达到了将频繁触发变为少量触发的目的。