手写防抖 debounce
代码实现
function debounce(fn, delay, immediate = false) {
let timer = null;
return function (...args) {
const context = this;
const callNow = immediate && !timer;
clearTimeout(timer);
timer = setTimeout(() => {
timer = null;
if (!immediate) {
fn.apply(context, args);
}
}, delay);
if (callNow) {
fn.apply(context, args);
}
};
}笔记记录
手写防抖 debounce
是什么
防抖的规则是:高频事件持续触发时不执行,只有停止触发达到指定时间后才执行一次。
常见场景:
- 搜索框输入后发起请求
- 窗口尺寸变化后重新计算布局
- 表单内容停止修改后自动保存
怎么执行
每次触发时都做两件事:
- 用
clearTimeout取消上一个定时器。 - 重新创建一个
delay毫秒后执行的定时器。
因此,只要事件在 delay 内再次到来,倒计时就会重新开始。
触发 A -> 创建定时器
触发 B -> 取消 A,创建新定时器
触发 C -> 取消 B,创建新定时器
停止触发 -> 等待 delay -> 执行 C 携带的回调代码关键点
timer保存在闭包里,多次调用会共享同一个定时器。args要传给apply,不是未定义的arg。fn.apply(this, args)保留调用时的this和参数。- 当
immediate为true时,第一次触发会立即执行,后续触发仍会重置冷却时间。