立即执行防抖在首次触发时立刻调用回调,之后重置定时器抑制连续调用,仅当等待期结束后再次触发才重新获得立即执行资格;其实现通过callNow = immediate && !timer判断并统一管理定时器。

防抖函数支持立即执行(immediate),关键是在触发时立刻执行一次,之后进入等待期,等待期间的连续调用会被忽略,直到等待期结束才重新启用。
立即执行的逻辑怎么实现
普通防抖在每次触发后延迟执行;而 immediate 模式下,第一次触发就立刻运行回调,后续触发若在等待期内,则重置定时器,不执行回调——直到等待期静默结束,才允许下一次“立即执行”机会。
核心区别在于:是否在 首次触发时直接调用 fn,以及定时器是用于“延后下次执行”,还是用于“清除前一次的立即执行资格”。
带 immediate 参数的防抖函数写法
以下是一个简洁可靠的实现:
function debounce(fn, delay, immediate = false) {
let timer = null;
return function(...args) {
const callNow = immediate && !timer;
if (timer) clearTimeout(timer);
if (callNow) {
fn.apply(this, args);
} else {
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
}, delay);
}
};
}
- callNow = immediate && !timer:仅当开启 immediate 且当前无待执行定时器时,才立刻执行(保证首次触发即运行,且不会重复立刻执行)
- 每次调用都先清定时器,避免旧任务干扰
- 非 immediate 情况下,行为和传统防抖一致:延迟执行最后一次调用
- immediate 为 true 时,第一次调用立刻执行;之后若在 delay 内再次触发,会清掉 pending 的 setTimeout,但不会再次立刻执行;只有等 delay 后再触发,才会再次满足
!timer条件,从而再次立即执行
使用示例对比
假设监听输入框搜索:
-
普通防抖:
debounce(search, 300)→ 用户停止输入 300ms 后才发起请求 -
立即执行防抖:
debounce(search, 300, true)→ 用户一输入就发请求,然后 300ms 内再输不发,停满 300ms 后再输又立刻发
适合需要“快速响应首动 + 抑制高频后续”的场景,比如按钮点击防重复提交(首次点立刻生效,连点只算一次)。
注意事项
- 不能把
immediate和节流(throttle)混淆:节流是固定频率执行,防抖 immediate 是“首尾各一次”的节奏 - 记得保存返回的防抖函数引用,否则每次重新生成都会丢失 timer 状态
- 如果需要手动取消,可额外返回一个
cancel方法(扩展版常见做法)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











