函数的防抖与节流目的都是在于减少事件调用频率。
防抖场景:搜索场景,待用户停顿进行检测。
节流场景:验证码场景,60秒内不可以再次点击。
防抖与节流的区别
在多次连续执行中,防抖是执行最后一次,节流是执行第一次。比如上面我们提到的搜索就是检测用户最后输入值,验证码就是用户的第一次点击。
防抖
在前面的事件还没有执行完毕,又有了新的事件,那么取消前面的事件,执行新的事件。
var debounce = (fn, wait) => {
let timer = null
return (...value) => {
// 如果前面有待执行的timer,清除timer
if(timer) clearTimeout(timer)
// 构建最新的timer,放入执行队列
timer = setTimeout(()=>{
fn(value)
}, wait)
}
}
防抖升级:我们知道按照上面的话,我们在第一次输入的时候就要进行等待,这是没有必要的也影响到用户体验。 可以优化成:用户首次输入,执行不用等待->继续输入,进入防抖->抖动结束返回第一步
var debounce = (fn, wait) => {
let timer;
let first = true;
return (...value) => {
if (first) {
first = false;
return fn(value);
}
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn(value);
first = true;
}, wait);
};
};
let con = (...val) => console.log(...val);
let conPlus = debounce(con, 2000);
conPlus("frist");
conPlus("second");
conPlus("last");
节流
在前面的事件没有执行完毕,状态固定为不可执行,待执行完毕后更新状态。
var throttle = (fn, wait) => {
let canRun = true
return (...value) => {
// 检测状态,锁住状态则不可二次执行
if(canRun === false){
return
}
/*
* 可执行部分
*/
// 更改状态为不可执行
canRun = false
// 等待函数执行完毕
setTimeout(() => {
fn(value)
// 执行完毕后修改状态为可执行状态
canRun = true
}, wait)
}
}
看完上面的代码,节流是不是很像厕所检修,检修员进去先在门口树一块“不可用的”警示牌,修好之后把牌子拿走。