javascript中的throttle和debounce浅析
throttle
我们这里说的throttle就是函数节流的意思。再说的通俗一点就是函数调用的频度控制器,是连续执行时间间隔控制。主要应用的场景比如:
1.鼠标移动,mousemove事件
2.DOM元素动态定位,window对象的resize和scroll事件
有人形象的把上面说的事件形象的比喻成机关枪的扫射,throttle就是机关枪的扳机,你不放扳机,它就一直扫射。我们开发时用的上面这些事件也是一样,你不松开鼠标,它的事件就一直触发。例如:
varresizeTimer=null; $(window).on('resize',function(){ if(resizeTimer){ clearTimeout(resizeTimer) } resizeTimer=setTimeout(function(){ console.log("windowresize"); },400);
debounce
debounce和throttle很像,debounce是空闲时间必须大于或等于一定值的时候,才会执行调用方法。debounce是空闲时间的间隔控制。比如我们做autocomplete,这时需要我们很好的控制输入文字时调用方法时间间隔。一般时第一个输入的字符马上开始调用,根据一定的时间间隔重复调用执行的方法。对于变态的输入,比如按住某一个建不放的时候特别有用。
debounce主要应用的场景比如:
文本输入keydown事件,keyup事件,例如做autocomplete
这类网上的方法有很多,比如Underscore.js就对throttle和debounce进行封装。jQuery也有一个throttle和debounce的插件:jQuerythrottle/debounce,所有的原理时一样的,实现的也是同样的功能。再奉上一个自己一直再用的throttle和debounce控制函数:
/* *频率控制返回函数连续调用时,fn执行频率限定为每多少时间执行一次 *@paramfn{function} 需要调用的函数 *@paramdelay {number} 延迟时间,单位毫秒 *@paramimmediate {bool}给immediate参数传递false绑定的函数先执行,而不是delay后后执行。 *@return{function}实际调用函数 */ varthrottle=function(fn,delay,immediate,debounce){ varcurr=+newDate(),//当前事件 last_call=0, last_exec=0, timer=null, diff,//时间差 context,//上下文 args, exec=function(){ last_exec=curr; fn.apply(context,args); }; returnfunction(){ curr=+newDate(); context=this, args=arguments, diff=curr-(debounce?last_call:last_exec)-delay; clearTimeout(timer); if(debounce){ if(immediate){ timer=setTimeout(exec,delay); }elseif(diff>=0){ exec(); } }else{ if(diff>=0){ exec(); }elseif(immediate){ timer=setTimeout(exec,-diff); } } last_call=curr; } }; /* *空闲控制返回函数连续调用时,空闲时间必须大于或等于delay,fn才会执行 *@paramfn{function} 要调用的函数 *@paramdelay {number} 空闲时间 *@paramimmediate {bool}给immediate参数传递false绑定的函数先执行,而不是delay后后执行。 *@return{function}实际调用函数 */ vardebounce=function(fn,delay,immediate){ returnthrottle(fn,delay,immediate,true);