JavaScript中的函数防抖与函数节流

概念

函数防抖(debounce)当调用动作过n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间。

函数节流(throttle)预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期。

函数节流(throttle)与 函数防抖(debounce)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。

比如如下的情况:window对象的resize、scroll事件拖拽时的mousemove事件文字输入、自动完成的keyup事件。

区别

可以拿我们平时坐电梯为例来形象地表述二者的区别:

函数防抖:如果有人进电梯(触发事件),那电梯将在10秒钟后出发(执行事件监听器),这时如果又有人进电梯了(在10秒内再次触发该事件),我们又得等10秒再出发(重新计时)。

函数节流 :保证如果电梯第一个人进来后,10秒后准时运送一次,这个时间从第一个人上电梯开始计时,不等待,如果没有人,则不运行。

应用场景

函数防抖的应用场景
连续的事件,只需触发一次回调的场景有:搜索框搜索输入。只需用户最后一次输入完,再发送请求手机号、邮箱验证输入检测窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。

函数节流的应用场景
间隔一段时间执行一次回调的场景有:滚动加载,加载更多或滚到底部监听谷歌搜索框,搜索联想功能高频点击提交,表单重复提交

实现

函数防抖:

function _debounce(fn,wait,time){
    var previous = null; //记录上一次运行的时间    
    var timer = null;    
    return function(){        
    var now = +new Date();        
    if(!previous) previous = now;        //当上一次执行的时间与当前的时间差大于设置的执行间隔时长的话,就主动执行一次        
    if(now - previous > time){           
     clearTimeout(timer);            
     fn();            
     previous = now;// 执行函数后,马上记录当前时间        
     }else{            
     clearTimeout(timer);            
     timer = setTimeout(function(){                
     fn();            
     },wait);        
     }    
     }}
     function _log(){   
      console.log(1)
      }
      window.onscroll = _debounce(_log,500,2000)

函数节流:

function _throttle(fn, time) { 
  let _self = fn,       
  timer,        
  firstTime = true //记录是否是第一次执行的flag  
  return function() {     
  let args = arguments, //解决闭包传参问题        
  _me = this //解决上下文丢失问题    
  if(firstTime) { //若是第一次,则直接执行      
  _self.apply(_me, args)      
  return firstTime = false    
  }    
  if(timer) { //定时器存在,说明有事件监听器在执行,直接返回      
  return false    
  }    
  timer = setTimeout(function() {       
  clearTimeout(timer)      
  timer = null      
  _self.apply(_me, args)    
  }, time || 500)  
  }
  }
  function _log(){    
  console.log(1)
  }
  window.onscroll = _throttle(_log,500)

总结

其实函数节流与函数防抖的原理非常简单,巧妙地使用 setTimeout 来存放待执行的函数,这样可以很方便的利用 clearTimeout 在合适的时机来清除待执行的函数。
使用函数节流与函数防抖的目的,就是为了节约计算机资源。

发布了32 篇原创文章 · 获赞 76 · 访问量 9910

猜你喜欢

转载自blog.csdn.net/liuyifeng0000/article/details/104354660