1.函数防抖
定义:当持续触发一个事件时,在n秒内,事件没有再次触发,此时才会执行回调;如果n秒内,又触发了事件,就重新计时只要最后一次操作,这样就防止了用户触发事件过于频繁的问题。
这里列举几个场景:搜索框:防止用户不断输入过程中,不断请求资源,n秒内只发送1次,用防抖来节约资源,或按钮提交场景,比如点赞,表单提交等,防止多次提交。
最常见的情况就是比如当我们在input框中传递数据时,不使用节流就会不断的发送数据请求,但是使用节流后,只有当你在指定间隔时间内没有输入,才会执行发送数据请求的函数。这样就防止AJAX请求的反复调用,大大减少了开销。
理解:类比一个实际情况,就好像小区的自动门,当一直有人进门(连续触发),大门不会关闭,在最后一个人进入之后一定时间间隔内没有人进入(停止连续触发)才会关闭。
实现:这里主要用到了闭包和定时器setTimeout这个函数,如果在100ms内没有再次触发滚动事件,那么就执行函数。如果在100ms内再次触发滚动事件,那么当前的计时取消,重新开始计时。
function debounce(fn,delay){
let timer = null //借助闭包
return function() {
if(timer){
clearTimeout(timer);
}
timer = setTimeout(fn,100)
}
}
}
2.函数节流
定义:所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。控制高频事件的执行次数。
如果在限定时间段内,当我们给对象绑定了onscroll函数后,当我们不断触发滚动事件,只要不停止触发,理论上就会在几秒钟触发很多次,如果我们在滚动中包含一些类似于交互数据这种消耗性能的操作时,就需要进行节流减少这种操作的执行次数。
相比于防抖节流只是控制执行次数,防抖则是为了之执行最后一次。
实现:这样也用到了闭包和定时器setTimeout这个函数,和防抖思路类似,但是算法略有不同。
window.onscroll = throttle(function(){
console.log("hello world")
},100)
function throttle(fn,delay){
let flag = true;
return function(){
if(flag){
setTimeout(()=> {
fn.call(this);
flag = true; },delay)
}
flag=false;
}
}
运行以上代码的结果是:如果一直拖着滚动条进行滚动,那么会以100ms的时间间隔,持续输出当前函数(hello world),实现了节流效果。