节流
实现节流的过程实际是闭包。
throttle里边有局部变量timer,第一次(0秒)触发input事件时,timer的值是
null,所以,不退出。
让fn函数等待1000毫秒后执行。
在1000毫秒内,再次触发ninput事件时,因为timer的值变成了延时执行对象,所以
退出了(不会重复setTimeout)。
为什么要在settimeout中采用箭头函数,因为,内部的this,arguments需要用闭包
函数的this和arguments。
为要用fn.apply(this,arguments)因为fn函数需要有明确的this指向(触发事件的元素)
event对象也需要非常使用。
ele.oninptu = throttle(function(){},1000);
function throttle(fn,delay){
let timer = null;
return function{
if(timer){
return
}
timer = settimeout(() => {
fn.apply(this,arguments);
timer = null;
},delay)
}
}
防抖
当一个函数连续被调用时,只执行最后一次。
登录、发短信等按钮避免用户点击太快,以致于发送了多次请求,需要防抖
ele.onclick = deboundce(function(){
console.log();
},500)
function deboundce(fn,delay){
let timer = null;
return function{
if(timer){
clearsetTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this,arguments);
timer = null;
},delay);
}
}
区别
节流和防抖的区别主要在于判断上次的等待事件还没执行时的处理方式不同:
节流判断上次的等待事件没有执行,会忽略当次事件。
防抖判断上次的等待事件没有执行,会清除上次的等待,重新开始一个新的等待。
let timer = null;
elem.oninput = function () {
if (timer) { return }
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, delay);
};
为什么使用apply
使用闭包后,闭包函数的this指向及event对象的获取会中断,所以采用apply将this指向及参数传递给fn函数。