参考一:函数防抖与节流
参考二:浅谈js防抖与节流
防抖(debounce):在第一次触发事件时,不立即执行函数,而是给出一个延迟。若在延迟时间内,不再触发事件那么执行函数;若在延迟时间内再次触发事件,那么以最后一次触发的时机重新计算延迟时间再执行函数。其实从名字也可以看出来,这个技术的出现就是解决用户手抖的情况(#…#)
实现如下:
function debounce(fn,delay=500){
let timer = null
return function(){
let args = arguments
timer&&clearTimeout(timer)
timer = setTimeout(()=>{ fn.apply(this,args) },delay)
}
}
// test
let log = debounce(function(a){
console.log(a)
})
btn.onClick=log(1)
wait!!! 这里防抖虽然是防抖了,但是给用户的感觉是有500ms的延迟,所以我想做个优化,让它第一次就开始执行了,且上次执行完毕后又可以立即执行,即用户手抖开始前立刻执行函数,用户手抖结束后再执行函数,然后继续重复下一轮,总之不能为了面试而面试对吧?
function myDebounce(fn,delay=500){
let timer = null
let flag = 1 // 立即执行标志 1^1 == 0; 0^1 == 1
return function(){
let args = arguments
timer&&clearTimerout(timer)
if(flag){
flag^=1
fn.apply(this,args)
timer = setTimeout(()=>{ flag^=1 },delay)
return
}
timer = setTimeout(()=>{ fn.apply(this,args); flag^=1 },delay)
}
}
节流
节流(throttle):如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效
function throttle(fn,holdTime=500) {
let timeout,
startT = +new Date
return function () {
clearTimeout(timeout)
let args = arguments
curT = +new Date
if(curT-startT>=holdTime){
fn.apply(this,args)
startT = curT
}
else{
timeout = setTimeout(() => { fn.apply(this,args)}, holdTime)
}
}
}



