防抖和节流都是利用了闭包原理、定时器原理。而因为使用闭包原理,所以如果使用不当会造成内存泄漏,需要将定时器清除。
防抖
防抖是执行最后一次,在事件触发后等待指定延迟时间才执行
适用的场景:输入框联想、窗口 resize 事件
function debounce(func, wait, immediate) {
let timeout;
const debounced = function(...args) {
const context = this;
if (timeout) clearTimeout(timeout);
if (immediate) {
const callNow = !timeout; // 如果定时器不存在,则表示可以立即执行
timeout = setTimeout(() => {
timeout = null;
}, wait);
if (callNow) func.apply(context, args);
} else {
timeout = setTimeout(() => {
func.apply(context, args);
}, wait);
}
};
debounced.cancel = () => clearTimeout(timer); // 提供取消方法
return debounced;
}
节流
节流是每段时间执行一次,在指定时间范围内,只执行一次
适用的场景:页面滚动加载、按钮防止重复点击
function throttle(func, wait) {
let timer = null;
let lastTime = 0;
const debounced = function(...args) {
const context = this;
const now = Date.now();
const remaining = wait - (now - lastTime); // 计算距离下次执行还剩多少时间
if (remaining <= 0) {
// 剩余时间小于等于0,说明可以立即执行
if (timer) {
clearTimeout(timer);
timer = null;
}
func.apply(context, args);
lastTime = now;
} else if (!timer) {
// 否则,如果定时器不存在,就设置一个定时器在剩余时间后执行
timer = setTimeout(() => {
lastTime = Date.now();
timer = null;
func.apply(context, args);
}, remaining);
}
};
debounced.cancel = () => clearTimeout(timer); // 提供取消方法
return debounced;
}
如何选择?
选择防抖:当你关心的是事件的最终状态。例如,等待用户输入完毕后再进行搜索。
选择节流:当你关心的是事件的持续过程,但需要降低频率。例如,在滚动页面时,定期检查用户是否滚动到了底部
评论区