深入理解防抖与节流

449 阅读2分钟

日常开发过程中,滚动事件做复杂计算频繁调用回调函数很可能会造成页面的卡顿,这时候我们更希望把多次计算合并成一次,只操作一个精确点,JS把这种方式称为debounce(防抖)和throttle(节流)

防抖

概念: debounce。其概念其实是从机械开关和继电器的“去弹跳”(debounce)衍生 出来的,基本思路就是把多个信号合并为一个信号。 即: 将多次事件触发, 合并成一个。 实现:通过定时间调用函数, 通过一个必报接收定时器, 如果在定时器时间内再次调用改方法,则清空定时器,重新创建新的定时器。从而达到多次频繁点击时间只调用一次。 意义: 减少不必须要的性能损耗 代码实现:

function debounce(func, delay) {
  let timeout
  return function() {
    clearTimeout(timeout) // 如果持续触发,那么就清除定时器,定时器的回调就不会执行。
    timeout = setTimeout(() => {
      func.apply(this, arguments)
    }, delay)
  }
}

节流

概念: 节流的意思是让函数有节制地执行,而不是毫无节制的触发一次就执行一次。什么叫有节制呢?就是在一段时间内,只执行一次。 实现:通过闭包变量,判断是否调用了定时器方法,如果调用则返回,没有则触发定时器,并改变变量 意义: 减少不必须要的性能损耗,在n秒值时间只触发了一次 代码实现:

function throttle(func, delay) {
    let run = true
    return function () {
      if (!run) {
        return  // 如果开关关闭了,那就直接不执行下边的代码
      }
      run = false // 持续触发的话,run一直是false,就会停在上边的判断那里
      setTimeout(() => {
        func.apply(this, arguments)
        run = true // 定时器到时间之后,会把开关打开,我们的函数就会被执行
      }, delay)
    }
  }

节流与防抖的区别

节流的实现方法为: 一段时间内,时间只执行一次, 如果事件在这段时间内,再次被点击, 则直接返回,不调用定时器的方法 防抖的实现方法为: 一段时间内,事件再次调用,则重新创建定时器任务,多次点击,事件执行的事件会更久。