函数节流

 


//多次触发某个动作,如onresize事件,窗口变化时会连续触发多次resize事件,消耗性能。可采取在一定时间内触发一次,取消掉无效的触发动作的执行。
//实现方式1::  指定时间间隔调用delayMethod返回的函数

//每次调用时,清除上一次的定时器,重新设置一个定时器

function delayMethod(method,wait){
var timerId = null;
return function(){
var args = arguments;
var context = this;
clearTimeout(timerId);
timerId = setTimeout(function(){
method.apply(context,args);
},wait);
}
}
}
//调用方式
var wrapHanlder = delayMethod(evtHandler,500);
$(window).on("resize",function(){
var params = {};
wrapHanlder(params); 
}
})

underscore中的实现:

如果已经设置过定时器则不再设置,等待设定的时间间隔后执行操作,执行完成后重置定时器,timer=null,下次再出发该操作时,再设置定时器。

/**
* 函数节流
* @param func 事件处理函数
* @param wait 延迟的时间间隔
* @param immediate 是否立即执行,默认false
* @return 返回事件处理函数
*/
function debounce(func, wait, immediate) {
var timeout, args, context, timestamp, result;
//immediate默认为false
// 当wait指定的时间间隔期间多次调用_.debounce返回的函数,则会不断更新timestamp的值,导致last < wait && last >= 0一直为true,从而不断启动新的计时器延时执行func
var later = function() {
var last = +new Date() - timestamp;
console.log("last 时间间隔 < 设置的 wait",last,wait);
if (last < wait && last >= 0) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
if (!immediate) {
result = func.apply(context, args);
if (!timeout) context = args = null;
}
}
};

return function() {
context = this;
args = arguments;
timestamp = +new Date();
// 第一次调用该方法时,且immediate为true,则调用func函数
var callNow = immediate && !timeout;
// 在wait指定的时间间隔内首次调用该方法,则启动计时器定时调用func函数
console.log("timeout",timeout);
if (!timeout) { console.log("timeout为null时,重新设置定时器");
timeout = setTimeout(later, wait);
}
if (callNow) {
result = func.apply(context, args);
context = args = null;
}

return result;
};
};

 

posted @ 2017-02-13 14:09  freewalker  阅读(186)  评论(0编辑  收藏  举报