秒懂 JavaScript 的防抖和节流

防抖(debounce)

在一定时间内触发同一事件,函数只会在最后一次点击后执行。

可以理解为游戏中的“回城技能”,按了之后需要等待一段时间才能实现回城,中途任意一次重按都需要重新等待。

// func是用户传入需要防抖的函数
// wait是等待时间
function debounce(fn, wait) {
    let timer = null //借助闭包
    return function(...args) {
        // 进入该分支语句,说明当前正在一个计时过程中,并且又触发了相同事件。
        // 所以要取消当前的计时,重新开始计时
        if (timer) clearTimeout(timer) 
        timer = setTimeout(() => {
            fn.apply(this, args)
        }, wait) // 进入该分支说明当前并没有在计时,那么就开始一个计时
    }
}
复制代码

节流(throttle)

在一定时间内触发同一事件,函数立即执行一次后,该函数在指定的时间期限内不再工作,直至过了这段时间才能重新生效。

可以理解为游戏中的“普通技能”,在按了之后马上触发,但技能触发之后任你如何按键都无效,需要在等一定的冷却时间之后才能再次触发。

// func是用户传入需要节流的函数
// wait是等待时间
function throttle(fn, wait) {
    // 上一次执行该函数的时间
    let lastTime = 0
    return function(...args) {
        // 当前时间
        let now = +new Date()
        // 将当前时间和上一次执行函数时间对比
        // 如果差值大于设置的等待时间就执行函数
        if (now - lastTime > wait) {
            lastTime = now
            fn.apply(this, args)
        }
    }
}
复制代码

使用案例(example):

贴上一个案例,立马体验一下防抖和节流的效果吧。

<body>
  <button id="btn1">防抖点击</button>
  <button id="btn2">节流点击</button>
  <script>
    function debounce(fn, wait) {
      let timer = null
      return function (...args) {
        if (timer) clearTimeout(timer) 
        timer = setTimeout(() => {
          fn.apply(this, args)
        }, wait)
      }
    }

    function throttle(fn, wait) {
      let lastTime = 0
      return function (...args) {
        let now = +new Date()
        if (now - lastTime > wait) {
          lastTime = now
          fn.apply(this, args)
        }
      }
    }

    function say() {
      console.log('-------hello-------')
    }

    document.getElementById('btn1').onclick = debounce(say, 2000)
    document.getElementById('btn2').onclick = throttle(say, 2000)
  </script>
</body>
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享