谈谈debounce与throttle
发布于 3 年前 作者 juan18 1302 次浏览 来自 分享

debounce,防抖,常用于滚动、拖拽、resize事件,防止事件触发过于频繁导致卡顿
throttle,节流,常用于按钮点击、滚动事件,用来防止事件多次触发

为什么debounce和throttle都是用来防止事件多次/频繁触发,却是两个不同的方法呢?这个主要是看需求和场景的。
我们来看看简易实现:

  function debounce(callback, timeout=1000) {
    let timer
    return function() {
      clearTimeout(timer)
      timer = setTimeout(function() {
        callback()
      }, timeout)
    }
  }
  function throttle(callback, timeout=1000) {
    let canRun = true
    return function() {
      if (canRun) {
        canRun =  false
        callback()
        setTimeout(() => {
          canRun =  true
        }, timeout)
      }
    }
  }

debounce,调用后不立刻触发,等待一段时间没有新的调用后,再执行
throttle,调用后立刻触发,等待一段时间后,才能再次被触发,中途被触发的都直接丢弃

所以,遇到了需要防止重复触发的需求时,需要具体分析:

  1. 如果第一次调用不需要,而最后一次调用最重要,需要被保留,可以使用debounce;
  2. 如果第一次调用最重要,最后一次可有可无,则使用throttle;
  3. 如果最后一次和第一次调用都重要,则可以使用debounce的immediate版本

对于情况3,可以参考下面debounce增强版的实现:

  function debounce(callback, timeout=1000, immediately=false) {
    let timer
    let canRun = immediately
    return function() {
      if (canRun) {
        canRun = false
        callback()
      } else {
        clearTimeout(timer)
        timer = setTimeout(function() {
          callback()
        }, timeout)
      }
    }
  }

实现方案没有一成不变的,各位也可以自行用其他方案去实现相同的效果。

回到顶部