# 节流

函数节流:不管事件触发频率有多高,只在单位时间内执行一次。

# 时间戳

function throttle(fn, wait) {
  // 记录上一次执行的时间戳
  let previous = 0
  return function (...args) {
    // 时间间隔
    if (Date.now() - previous > wait) {
      previous = Date.now()
      fn.apply(this, args)
    }
  }
}

第一次事件肯定触发,最后一次不会触发(比如说监听 onmousemove,则鼠标停止移动时,立即停止触发事件)

# 定时器

function throttle(fn, wait) {
  let timer = null
  return function (...args) {
    if (!timer) {
      timer = setTimeout(() => {
        timer = null
        fn.apply(this, args)
      }, wait)
    }
  }
}

第一次事件不会触发(fn 是放在 setTimeout 中执行的,所以第一次触发事件至少等待 wait 毫秒之后才执行),最后一次一定触发

# 定时器和时间戳结合

两者结合可以实现,第一次事件会触发,最后一次事件也会触发

function throttle(fn, wait) {
  let previous = 0
  let timer = null
  return function (...args) {
    // 当前的时间戳
    if (Date.now() - previous > wait) {
      clearTimeout(timer)
      timer = null
      // 更新时间戳
      previous = Date.now()
      fn.apply(this, args)
    } else if (!timer) {
      // 设置下一个定时器
      timer = setTimeout(() => {
        timer = null
        fn.apply(this, args)
      }, wait)
    }
  }
}
Last Updated: 1/21/2022, 6:09:58 PM