函数节流throttle

684 阅读1分钟

在一些少数情况下,函数的触发不是由用户直接控制的。在这些场景下,函数有可能被非常频繁地调用,而造成大的性能问题。下面将列举一些这样的场景。

  • 出现场景
    • window.onresize 事件
    • mousemove 事件

原理

throttle 函数的原理是,首次调用立即执行, 后续调用放到定时器中, 延迟一段时间执行。 如果之前的延迟执行还没有完成,不重置定时器, 会忽略调用该函数的请求。

思想:每隔一段时间,只执行一次函数

实现

throttle 函数接受2个参数,第一个参数为需要被延迟执行的函数,第二个参数为延迟执行的时间

首次立即执行, 第二次开始使用定时器执行 fn 执行的函数 interval 延迟执行时间

/**
 * @description 函数节流: 每隔一段时间,只执行一次函数
 * @param { Function } fn 需要延迟执行的函数
 * @param { Number } interval 延迟执行的时间,默认值500ms
 */
export function throttle(fn, interval = 500) {
  // 记录定时器id
  let timer = null
  // 是否是第一次调用
  let isFirstTime = true

  return function () {
      const args = arguments
      const _me = this

      // 第一次直接执行,改变标志,无需延迟
      if (isFirstTime) {
          fn.apply(_me, args)
          return isFirstTime = false
      }

      // 不是第一次
      // 存在定时器,前面的延迟操作没有完成,直接返回,拒绝调用请求
      if (timer) {
          return false
      }

      // 延迟执行
      timer = setTimeout(() => {
          clearTimeout(timer)
          timer = null
          fn.apply(_me, args)
      }, interval)
  }
}

  • 使用
window.onresize = throttle(function () {
    console.log(1);
}, 2000)

防抖和节流

区别在于,防抖每次触发事件都重置定时器,而节流在定时器到时间后再清空定时器