函数的防抖与节流
-
防抖
- 外层函数(debounce函数)多次被调用时,想要防抖的函数只有第一次或者最后一次才会执行,也就是说持续快速的调用,只会执行一次,始终第二次的定时器会覆盖掉第一次的,如果大于规定时间,会执行,相反则不会
- 取第一次执行,函数这次能否执行取决于它的外层函数(debounce函数)这次和上一次被调用的时间差,如果超过规定,节流和防抖的执行结构没有区别,都会执行
- 取最后一次执行,函数这次能否执行取决于它的外层函数(debounce函数)这次和下一次被调用的时间差,如果超过规定,节流和防抖的执行结构没有区别,都会执行
- 如果没有超过规定时间则不会执行
-
let in1=document.getElementById('in1'); in1.addEventListener('input',throttle(request,1000)) // 取一段时间的最后一次 function debounce(fn,wite){ let timer; return function(...params){ if(timer) clearTimeout(timer); timer=setTimeout(()=>{ fn.apply(this,params) },wite) } } - 前面的所有的触发都会被取消,最后一次执行在规定的时间之后才会触发,也就是说如果持续快速的触发 只会执行一次
- 所谓防抖,就是指触发事件后 n 秒后才执行函数,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
-
节流
- 所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。
- 函数这次能否执行取决于它这次与上一次被调用的时间差,如果超过规定时间,节流和防抖的执行结构没有区别,都会执行。如果小于规定时间则不会执行
-
let in1=document.getElementById('in1'); in1.addEventListener('input',throttle(request,1000)) // 时间戳 function throttle(fn,dur) { var begin=0; return function (...params) { let cur=new Date().getTime(); if(cur-begin>dur){ fn.apply(this,params); begin=cur; } } } - 在规定的间隔时间返回内不会重复触发回调,只有大于这个时间间隔才会出发回调才会触发回调,把频繁触发变为少量触发
-
区别
-
时间间隔1秒,点击事件为例
- 当连续的两次点击都间隔1秒及以上,那么他们没有区别
- 当连续的两次点击间隔不满1秒时,他们有以下区别
防抖,取多次触发的第一次
in1.addEventListener('input',debounceF(request,1000)) // 取一段时间的第一次 function debounceF(fn,wite) { let timer; return function(...params){ if(timer) clearTimeout(timer); // 注意clearTimeout(timer)后,timer还是有值的,并非undefined或者null if(!timer){ fn.apply(this,params) } timer=setTimeout(()=>{ timer=null; },wite) } }第一次点击会立即执行函数,然而多长时间之后可以再次执行函数,这取决与连续点击的最后一次所设置的定时器,最后一次点击1秒之后,再点击可以再次执行函数
节流:第一次点击立即执行,1秒钟之后就可以执行第二次
-
假如防抖的函数是要在一秒钟之后执行
-
当零秒触发事件,在等待的一秒钟之内没有再次触发,那么一秒的时候会执行零秒触发事件的回调
-
如果在等待的一秒钟之内事件被再次触发,假如0.8秒是最后一次触发的时间那么,这0.8秒之前的所有定时器都会clear,然后从这0.8秒开始新一轮的循环,
- 如果0.8到1.8没被触发,1.8时执行0.8触发事件的回调
- 如果0.8到1.8有再次被触发,记录最后一次触发的时间开始新一轮的循环
-
如果是节流那就是1s中之内会执行一次
-
当零秒触发的事件,会立即执行,零到一秒就算有多次触发或者没有触发,都不会执行
-
无论0-1触发了几次最后一次,是多会触发,只有知道第一次是0秒触发,那么第二次执行的一定是1-2秒的第一次触发
\