防抖函数
函数防抖{debounce}:在用户频繁触发某个行为的时候,我们只识别一次触发
- 频繁触发条件是我们自己可以设定的,例如:我们设置的是500MS,这样只要用户在这段时间内操作两次及以上,就属于频发触发;但是如果是500MS之前触发一次,之后触发一次,这不算频繁触发…
- 我们可以控制是在开始触发还是结束触发
//公共类
const clearTimer = function clearTimer(timer) {
if (timer) {
clearTimeout(timer);
}
return null;
};
/*
* 函数防抖
*/
const debounce = function debounce(func, wait, immediate) {
if (typeof func !== 'function') throw new TypeError(`func must be a function`);
if (typeof wait === 'boolean') immediate = wait;
if (typeof wait !== 'number') wait = 500;
if (typeof immediate !== 'boolean') immediate = false;
let timer = null;
return function operate(...params) {
let now = !timer && immediate,
result;
timer = clearTimer(timer);
timer = setTimeout(() => {
// 结束边界触发:清除最后设置的定时器
timer = clearTimer(timer);
if (!immediate) result = func.call(this, ...params);
}, wait);
// 立即执行{开始边界触发}
if (now) result = func.call(this, ...params);
return result;
};
};
节流函数
函数的节流{throttle}:在用户频发触发某个行为的时候,原本的频率太快了「例如:5MS触发一次」,此时我们经过节流处理,可以降低这个频率「例如:我们降低到500MS一次」
/*
* 函数节流
*/
const throttle = function throttle(func, wait) {
if (typeof func !== 'function') throw new TypeError(`func must be an function`);
if (typeof wait !== 'number') wait = 500;
let timer = null,
previous = 0; //记录上一次操作的时间
return function operate(...params) {
let remaining = wait - (+new Date() - previous),
result;
if (remaining <= 0) {
// 两次操作间隔时间超过500MS{或者第一次触发}:立即执行函数
timer = clearTimer(timer);
result = func.call(this, ...params);
previous = +new Date();
return result;
}
// 间隔没有超过500MS,并且还没有设置过定时器计时,此时设置定时器,等待执行即可
if (!timer) {
timer = setTimeout(() => {
timer = clearTimer(timer);
func.call(this, ...params);
previous = +new Date();
}, remaining);
}
};
};
防抖和节流的区别
- 防抖:一小时内,只触发一次,因为一直在频繁操作
- 节流:如果按照原本的5MS点击一次,会触发72万次…现在我们根据节流降低了触发频率,让其间隔500MS才触发一次,所以最后只触发7200次…