函数防抖和节流的理解 - pod4g/tool GitHub Wiki

1. 防抖(debounce)

防抖相当于法师放技能读条,return出去的函数被触发时,读条被打断,然后重新读条,如果不被打断,等读条结束,会执行这个函数

一个最简单的实现:

function debounce(fn, delay) {
  // 法师读条定时器
  let timer
  // 这个return出去的函数才是真正触发的函数
  return function () {
   // 当这个函数被触发,法师读条结束(即清空法师读条定时器timer)
   clearTimeout(timer)
   const self = this
   const args = arguments
   // 重新读条
   timer = setTimeout(() => {
    // 只有当读条没有被打断过,才释放技能(即fn执行)
    fn.apply(self, args)
   })
 }
}

一个需要频繁触发的函数,在规定时间内,只让最后一次生效,前面的不生效

防抖的应用场景:

  1. 模糊查询(每次input事件都要发送请求)
  2. 每次 resize/scroll 触发统计事件

2. 节流(throttle)

节流相当于我们玩射击游戏,按住发射键不放,子弹并不是无限发射,还是间隔一段时间发射出去,即「匀速发射」

因为节省了子弹,故我们称其为「节流」

一个最简单的实现:

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

节流的应用场景:

  1. DOM 元素的拖拽功能实现(mousemove)
  2. 搜索联想(keyup)
  3. 计算鼠标移动的距离(mousemove)
  4. Canvas 模拟画板功能(mousemove)
  5. 射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹)
  6. 监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户停止滚动后,才会判断是否到了页面底部;如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次