防抖(debounce)和节流(throttle)

677 阅读1分钟
  • 防抖策略是将高频操作合并为一次执行,如果高频操作每次清空定时器,以最后一次操作为主。
  • 节流策略是将高频操作按周期执行,一个timeout 周期内执行一次,如果第一个周期执行完,有新的操作进来进行另一个周期。

防抖(debounce)

输入框change案例:不管输入change触发多少次,以最后一次值为准

  const input1=document.getElementById('input1')
    let timer =null
    input1.addEventListener('keyup',function(){
      if(timer){
        clearTimeout(timer)
        //clearTimeout(timer)是在内存中清除掉定时器
      }
      timer=setTimeout(()=>{
        console.log(input1.value);
        //清空定时器
        timer=null
      },500)
    })
debounce(fn,delay){
  // timer 是闭包中的
   let timer = null
   return function(){
     if(timer) clearTimeout(timer)
     timer = setTimeout(fn,delay)
   }
}
  function debounce(fn, delay = 500) {
  // timer 是闭包中的
  let timer = null

  return function () {
  if (timer) {
  clearTimeout(timer)
  }
  timer = setTimeout(() => {
  fn.apply(this, arguments)
  timer = null
  }, delay)
  }
  }

 input1.addEventListener('keyup', debounce(function (e) {
 console.log(e.target)
  console.log(input1.value)
 }, 600))
 

timer=null 和clearInterval(timer)区别

  • timer=null:初始化timer,也可以不写,也可以写成 timer = 0 或者 timer = undefined 

  • clearInterval(timer):清空定时任务,必须要写,否则定时任务就不停止

节流(throttle) drag拖拽案例:不管拖拽速度多快,都是每隔100ms触发

  const div1=document.getElementById('div1')
    let timer =null
    div1.addEventListener('drag',function(){
      if(timer){
        return
      }
      timer=setTimeout(()=>{
        console.log(e.offsetX,e.offsetY);
        //清空定时器
        timer=null
      },500)
    })
 function throttle(fn, delay = 500) {
  // timer 是闭包中的
  let timer = null

  return function () {
  if (timer) {
   return
  }
  timer = setTimeout(() => {
  fn.apply(this, arguments)
  timer = null
  }, delay)
  }
  }

 div1.addEventListener('drag', throttle(function (e) {
     console.log(e.offsetX,e.offsetY);
 }, 500))