跳至主要內容

防抖与节流

wzCoding大约 2 分钟综合知识防抖与节流

防抖与节流

防抖与节流是我们在开发中经常用到的工具函数,它们的作用是降低事件的触发频率,从而提高性能。

防抖函数

防抖函数的作用是在一定时间内,事件被触发 n 次,只会执行一次回调函数。如果在一定时间内事件再次被触发,则会重新计算执行时间。

function debounce(callback,delay){
   //设置定时器,用来表示事件是否触发过
   let timer = null
   return function(){
      //保存 this 上下文与参数
      let that = this
      let args = arguments
      
      //如果timer存在,表示重复触发了事件,清空已经存在的定时器(即取消即将执行的回调函数)
      if(timer){
         clearTimeout(timer)
         timer = null
      }
      
      //重新设置定时器,在到达给定的延迟后触发一次回调函数执行
      timer = setTimeout(()=>{
         callback && callback.apply(that,args)
      },delay)
   }
}

防抖函数经常用于输入框搜索事件、窗口大小变化事件等。

节流函数

节流函数的作用是在一定时间内只执行一次回调函数,如果在这个时间内再次被触发,不会执行,直到下一个时间段。

一般节流函数

function throttle(callback,delay){
   //设置定时器,表示事件是否触发
   let timer = null
   //记录开始时间,表示事件触发的时间,后续再次触发会更新这个时间
   let start = Date.now()
   return function(){
      //保存 this 上下文与参数
      let that = this
      let args = arguments
      
      //如果timer存在,表示重复触发了事件,清空已经存在的定时器(即取消即将执行的回调函数)
      if(timer){
         clearTimeout(timer)
         timer = null
      }
      //当重复触发事件后,计算给定的时间间隔与事件触发时间之间的的差值
      let remaining = delay - (Date.now() - start)

      if(remaining <= 0){
         //时间差值小于等于0 ,则说明已经到达给定的时间间隔,可以触发回调函数执行
         callback && callback.apply(that,args)
         start = Date.now()
      }else{
         //如果时间差值大于0,则说明还没有到达下一个时间间隔,将回调函数放入定时器中
         //等待到达给定的时间间隔后执行回调
         setTimeout(()=>{
            callback && callback.apply(that,args)
         },delay)
      }
   }
}

一般节流函数经常用于滚动事件、表单按钮提交事件等。

raf节流函数

function rafThrottle(callback,delay){
   //设置触发锁
   let lock = false

   return function(){

      //如果触发锁为true,说明事件已经触发过,直接返回
      if(lock){
         return
      }

      //如果触发锁为false,说明事件没有触发,此时可以触发回调执行,将触发锁设置为true
      lock = true

      //保存 this 上下文与参数
      let that = this
      let args = arguments
      
      //利用 requestAnimationFrame 函数来触发回调执行
      window.requestAnimationFrame(()=>{
         callback && callback.apply(that,args)
         lock = false
      })
         
   }
}

由 requestAnimationFrame 实现的节流函数适合用于控制执行与渲染相关的高频事件。