防抖debounce
防抖函数指的是某个函数在某段时间内,无论触发了多少次回调,都只执行最后一次。
假如我们设置了一个等待时间 3 秒的函数,在这 3 秒内如果遇到函数调用请求就重新计时 3 秒,直至新的 3 秒内没有函数调用请求,此时执行函数,不然就以此类推重新计时。
就是当事件触发后开启一个定时器,如果事件在这个定时器限定的时间内再次触发,则清除定时器,再写一个定时器,定时时间到则触发。
function debounce(fn, delay){
let timer = null;
return function(){
clearTimeout(timer);
timer = setTimeout(()=> {
fn.apply(this, arguments);
}, delay)
}
}
节流throttle
函数节流指的是某个函数在一定时间间隔内(例如 3 秒)执行一次,在这 3 秒内 无视后来产生的函数调用请求。
即可以设计一种类似控制阀门一样定期开放的函数,事件触发时让函数执行一次,然后关闭这个阀门,过了一段时间后再将这个阀门打开,再次触发事件。
function throttle(fn, delay){
let valid = true;
return function(){
if(valid) { //如果阀门已经打开,就继续往下
setTimeout(()=> {
fn.apply(this, arguments);//定时器结束后执行
valid = true;//执行完成后打开阀门
}, delay)
valid = false;//关闭阀门
}
}
}
// 刚开始valid为true,然后将valid重置为false,进入了定时器,在定时器的时间期限之后,才会将valid重置为true,valid为true之后,之后的点击才会生效
// 在定时器的时间期限内,valid还没有重置为true,会一直进入return,就实现了在N秒内多次点击只会执行一次的效果
//用法:
function fn(value){
console.log(value);
}
var throttleFunc = throttle(fn,2000);//节流函数
//事件处理函数,按钮点击事件
btn.addEventListener("click",function(){
throttleFunc(Math.random());// 给节流函数传参
})
应用场景
防抖
- search搜索联想,用户在不断输入值时,用防抖来节约请求资源
- window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
节流
- 鼠标不断点击触发,mousedown(单位时间内只触发一次)
- 监听滚动事件,比如是否滑到底部自动加载
总结
相同点
防抖和节流都是为了阻止操作高频触发,从而浪费性能
区别
- 防抖是触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。适用于可以多次触发但触发只生效最后一次的场景
- 节流是高频事件触发,但在n秒内只会执行一次,如果n秒内触发多次函数,只有一次生效,节流会稀释函数的执行频率