防抖与节流

145 阅读1分钟

防抖与节流

防抖与节流都是提高代码性能的方式,只是实现的方式不同。

它们主要通过 减少事件处理函数的执行次数 来实现性能的优化。简单来说就是触发多次事件但是只执行一次函数。

要实现防抖与节流,都要用到定时器。

节流

在一定时间内 多次触发只会执行一次(第一次)。也就是说在第一次触发之后的一定时间范围内,再次触发是不会执行事件处理函数的。

节流的实现依赖两个元素:判断变量跟定时器。

具体实现

<button @click="handler">按钮</button>
data() {
  return {
    flag: true // 用来判断是否可以执行处理函数的变量
  }
},

handler() {
  if(this.flag) {
    this.flag = false
    
    setTimeout(() => {
      // 真正的处理函数
      fn()
      
      this.flag = true
    }, 500)
  }
}

代码可优化如下:

data() {
  return {
    flag: null
  }
},

handler() {
  if(!this.flag) {
    this.flag = setTimeout(() => {
      // 真正的处理函数
      fn()
      
      this.flag = null
    }, 500)
  }
}

可封装为一个方法:

throttle(fn, delay = 500) {
  let flag = null
  
  return function(...args) {
    if(!flag) {
      flag = setTimeout(() => {
        fn.apply(this, ...args) // 真正的处理函数
      
        flag = null
      }, delay)
    }
   }
  }

使用场景

  • 上拉加载来回滚动触发加载事件

防抖

多次触发时执行 最后一次 触发的事件处理函数

具体实现

防抖实现的前提是事件处理函数必须有延时,否则的话是无法实现的。

<button @click="handler">按钮</button>
data() {
  return {
    timer: null
  }
},

handler() {
  clearTimeout(this.timer)
    
  this.timer = setTimeout(() => {
    fn()
  }, 500)
}

可封装为一个方法:

debounce(fn, delay = 500) {
  let timer
  
  return function(...args) {
    clearTimeout(timer)
    
    timer = setTimeout(() => {
      fn.apply(this, ...args)
  }, delay)
  }
}

使用场景

  • 搜索框输入