防抖和节流


在 JavaScript 中,防抖(Debounce)和节流(Throttle)是两种常用的优化高频率触发事件的技术,它们的核心目的都是限制函数的执行频率,但应用场景和实现方式有所不同。

防抖(Debounce)

概念:在一定时间内,只有最后一次调用函数才会被执行。 应用场景:搜索框实时联想、窗口大小调整、按钮重复点击等。

实现:

export function debounce<T extends unknown[]>(
  func: (...arg: T) => unknown,
  delay: number
) {
  let timer: number
  return function (this: unknown, ...args: T) {
    if (timer) {
      window.clearTimeout(timer)
    }
    timer = window.setTimeout(() => {
      func.apply(this, args)
    }, delay)
  }
}

节流(Throttle) 概念:在一定时间内,函数只能执行一次。 应用场景:滚动加载、高频点击、窗口滚动事件等。

实现

export function throttle<T extends unknown[]>(
  func: (...arg: T) => unknown,
  delay: number
) {
  // 记录上一次执行函数的时间
  let lastExecTime = 0
  // 定时器ID
  let timer: number
  return function (this: unknown, ...args: T) {
    // 获取当前时间
    const currentTime = Date.now()
    // 如果当前时间与上一次执行函数的时间间隔大于或等于指定的延迟时间
    if (currentTime - lastExecTime >= delay) {
      // 清除定时器
      window.clearTimeout(timer)
      // 执行传入的函数
      func.apply(this, args)
      // 更新上一次执行函数的时间
      lastExecTime = currentTime
    } else {
      // 清除定时器
      window.clearTimeout(timer)
      // 设置定时器,在指定的延迟时间后执行函数
      timer = window.setTimeout(() => {
        // 执行传入的函数
        func.apply(this, args)
        // 更新上一次执行函数的时间
        lastExecTime = currentTime
      }, delay)
    }
  }
}

对比:

防抖(Debounce) 节流(Throttle)
只执行最后一次调用 固定频率执行
适合需要避免重复操作的场景 适合需要限制执行频率的场景
例如:搜索联想、按钮防双击 例如:滚动加载、窗口 resize