防抖是为了避免像预期的那样频繁触发一些监控事件。或者在一些监控命令中,会频繁触发事件,比如resize,mousemove等。非稳定例子varcount=0,Elem=doc.getElementById('con')functionappendCount(e){console.log(e);元素。innerHTML=count++}//正常,不加防抖,直接监听执行Elem.addEventListener('mousemove',function(){appendCount()})这会导致Eelm.innerHTML只要鼠标移动就不断变化。现在好像没有问题了。如果渲染了很多数据或者请求了数千个列表数据怎么办?会导致浏览器不断回流和重绘。那么如何稳定呢??在触发mousemove时间后的1s内,只有mousemove方法没有被触发,appendCount()才会被执行。varcount=0,Elem=doc.getElementById('con');functiondebounce(fn,waitTime){//定义定时器vartimeoutFn=null;returnfunction(){//清除定时器clearTimeout(timeoutFn);//重置定时器timeoutFn=(()=>{fn.apply(this,arguments)},waitTime)}}functionappendCount(){ELem.innerHTML=count++;}Elem.addEventListener('mousemove',debounce(appendCount,500))防抖处理mousemovetrigger,triggerdebounce()`定义一个定时器timeoutFn,返回执行内容:清空当前timeoutFn定时器(timeoutFn=null;),定义执行内容。//debounce()返回内容function(){//清除定时器clearTimeout(timeoutFn);//resettimertimeoutFn=(()=>{fn.apply(this,arguments)},waitTime)}当mousemove再次触发,timeoutFn定时器再次清空,重新定义执行内容只等到最后一次mousemove,定时器没有被debounce()timeoutFn定时器清零,最后执行fn.apply(this,agruments);throttling是比较防抖的,我对throttling是这样理解的:当我们想在一段时间内并且只触发一次这样的事件时,可以更多的节省我们的资源和网络请求。以上面的AppendCount()为例,我只想在3s内触发一次AppendCount()事件。那我们应该怎么处理呢?varcount=0,Elem=doc.getElementById('con');functionthrottle(fn,waitTime){vartimeoutFn=null;returnfunction(){//如果有timeoutFn定时器,等待timeoutFn完成if(!timeoutFn){timeoutFn=(()=>{//空定时器clearTimeout(timeoutFn)fn.apply(this,arguments)},waitTime)}}}functionappendCount(){ELem.innerHTML=count++;}Elem.addEventListener('mousemove',throttle(appendCount,3000))这个和防抖不同的是,它是等待timeoutFn执行完毕,通过clearTimeout(timeoutFn)清除,这样3s后可以再次执行timeoutFn。还有一种写法,和上面的有点不同。上面是第一秒触发throttle的时候,但是appendCount只能在第四秒执行。但是下面会立即执行。第一秒触发throttle时,会执行appendCount,第四秒后再次发送throttle。varcount=0,Elem=doc.getElementById('con');functionthrottle(fn,waitTime){//定义定时器,执行状态vartimeoutFn=null,isRuning=false;returnfunction(){//如果不在执行状态if(!isRuning){//开启执行状态isRuning=true;//定义定时器timeoutFn=(()=>{fn.apply(this,arguments);//执行完成,关闭执行状态isRuning=false;},waitTime)}}}functionappendCount(){ELem.innerHTML=count++;}Elem.addEventListener('mousemove',throttle(appendCount,3000))参考JavaScript专题:LearnthrottlingwithunderscoreJavaScript专题:Learnanti-shakewithunderscore
