总结防抖函数和节流函数的区别(简易版)

这是我参与更文挑战的第15天,活动详情查看: 更文挑战

写在前言

在我们写页面的过程中,很多时候我们需要对页面的行为进行监听,比如滚动,键盘输入,鼠标移动等等,这些js都有提供事件给我们调用,比如onscroll, oninput, onmousemove
但是浏览器触发这些事件是很灵敏的。比如滚动,可能你就滚动50px,但是已经触发十几次事件甚至更多,这会极大影响浏览器的性能,如果涉及到后台接口,可能还会把服务端搞崩了。

怎么避免这种行为?

这时候防抖函数节流函数就派上用场了。

防抖函数(debounce)

设定一个时间间隔,如果前后2次事件的时间间隔大于设定的时间间隔,会执行对应的函数,否则不会执行。

举个例子:
比如滚动事件,设置时间间隔是100ms, 你一直在不停滚动,我不会一直执行滚动事件对应的函数,我只会在你停下来且隔100ms后才会执行;如果你停下来了,但是你在100ms内又滚动了,则不会执行。

跟触发事件的频率有关,频率间隔超过设定的间隔,就会执行,否则不会。

那么代码该怎么实现呢? 主要是用到setTimeoutclearTimeout函数

// 防抖函数
function debounce(fn, delay = 100) {
  let timer = null
  return function (...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn(...args)
    }, delay)
  }
}
// 监听滚动事件
window.addEventListener('scroll', debounce(function () {
  console.log('scroll事件触发了')
}))
复制代码

支持2个参数,一个是事件对应的函数,一个是设定的时间间隔,单位ms

原理解析:
一开始先设置setTimeout,如果下个事件的时间间隔没有超过设置的delay就触发了,则会clearTimeout, 然后重新设置个setTimeout,直到时间间隔超过设置的delay才会执行,后面依此类推。

节流函数(throttle)

设定一个时间间隔,比如1000ms, 在1000ms无论触发多少次事件,但是只会执行一次函数。

那么代码该怎么实现呢?和防抖函数类似,主要是用到setTimeoutclearTimeout函数,但是 clearTimeout放的位置不一样。

function throttle(fn, delay = 1000) {
  let timer
  return function (...args) {
    if (timer) return
    timer = setTimeout(() => {
      clearTimeout(timer)
      // clearTimeout后还要销毁timer
      timer = null
      fn(...args)
    }, delay)
  }
}
// 监听滚动事件
window.addEventListener('scroll', throttle(function () {
  console.log('scroll事件触发了')
}))
复制代码

支持2个参数,一个是事件对应的函数,一个是设定的时间间隔,单位ms

原理解析:
一开始先设置setTimeout, 如果setTimeout还没执行的话,下次会return。直到执行setTimeout里的函数后才会设置下一个setTimeout,后面依此类推。这就保证在设定的时间间隔里面,只会执行一次。

二者区别

防抖函数跟触发事件的频率有关,只要你触发的时间间隔超过设定的时间间隔,那么就会执行函数,否则就不会。
而节流函数跟时间有关,在设定的时间间隔里面,只会执行一次函数。

应用场景

应用场景其实是很灵活的,并没有限定哪个场景一定要用哪个函数。

比如说滚动事件,我觉得要在滚动停下来后再执行滚动事件,那么就可以用防抖函数;如果我觉得我要每隔1s执行一次滚动事件,那么就可以用节流函数。

只要你理解了这两种函数,再结合产品的需求,最后决定用哪个。

总结

以上就是我总结的防抖函数和节流函数,希望对你们理解防抖函数和节流函数有所帮助~

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享