函数节流(throttle)与函数去抖(debounce)

以下场景往往由于事件频繁被触发,因而频繁执行DOM操作、资源加载等重行为,导致UI停顿甚至浏览器崩溃。

  •   1. window对象的resize、scroll事件
  •   2. 拖拽时的mousemove事件
  •   3. 射击游戏中的mousedown、keydown事件
  •   4. 文字输入、自动完成的keyup事件

  实际上对于window的resize事件,实际需求大多为停止改变大小n毫秒后执行后续处理;而其他事件大多的需求是以一定的频率执行后续处理。针对这两种需求就出现了debounce和throttle两种解决办法。

什么是debounce函数去抖

如果用手指一直按住一个弹簧,它将不会弹起直到你松手为止。

也就是说当调用动作n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间

简单的实现方式

空闲控制 返回函数连续调用时,空闲时间必须大于或等于 idle,action 才会执行
* @param idle   {number}    空闲时间,单位毫秒
* @param action {function}  请求关联函数,实际应用需要调用的函数
* @return {function}    返回客户调用函数
*/
debounce(idle,action)

var debounce = function(idle, action){

  var last

  return function(){
    var ctx = this, args = arguments
    clearTimeout(last)
    last = setTimeout(function(){
        action.apply(ctx, args)
    }, idle)
  }
}

什么是throttle函数节流
如果将水龙头拧紧直到水是以水滴的形式流出,那你会发现每隔一段时间,就会有一滴水流出。
也就是会说预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期

简单的实现方式
function _throttle(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)
 

或者可以这样理解

var canRun = true;

document.getElementById("throttle").onscroll = function(){
if(!canRun){
// 判断是否已空闲,如果在执行中,则直接return
return;
}

 

canRun = false;
setTimeout(function(){
console.log("函数节流");
canRun = true;
}, 300);
};




猜你喜欢

转载自www.cnblogs.com/Marinnn/p/9353634.html