立即执行防抖函数首次调用即运行回调,后续触发仅重置定时器,等待期结束不执行;通过immediate标志位控制,callnow判断是否立即执行,settimeout仅重置状态。

支持立即执行的防抖函数,核心在于:首次调用时立刻执行,后续在等待时间内重复触发则重置定时器,等待时间结束后不再执行;若等待时间结束前无新触发,则不额外执行。
关键逻辑:区分“立即执行”和“延迟执行”两个阶段
普通防抖只在停止触发后执行一次。而立即执行版需在第一次调用时同步运行回调,之后进入“防抖窗口期”,期间新调用仅刷新定时器,窗口期结束后不补执行。
- 用一个标志位(如 isImmediate)标识是否启用立即执行模式
- 首次调用时,若 isImmediate 为 true,立即执行回调,并启动定时器用于后续“冷却”
- 定时器内不做回调执行,仅将标志位重置为可再次立即触发的状态(即允许下一次调用再次立即执行)
- 注意:不能在定时器里再执行回调,否则会违背“只首次立即执行”的要求
基础实现代码(带注释)
以下是一个简洁、可直接使用的立即执行防抖函数:
function debounce(func, wait, immediate = false) {
let timeout = null;
return function executedFunction() {
const later = () => {
// 冷却期结束,重置状态,允许下次立即执行
timeout = null;
if (!immediate) {
func.apply(this, arguments);
}
};
const callNow = immediate && !timeout;
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(later, wait);
if (callNow) {
func.apply(this, arguments);
}
};
}
说明:
- immediate = false 是默认行为(标准防抖);设为 true 即启用立即执行模式
- callNow 判断:仅当 immediate 为 true 且当前无待执行定时器(!timeout)时,才首次立即执行
- 每次新调用都会 clearTimeout 并重设,确保只有最后一次“空档”可能触发延迟执行(但 immediate 模式下,延迟部分只负责清理状态,不执行 func)
使用示例与效果对比
假设绑定到输入框的搜索事件:
const search = debounce(() => {
console.log('发起搜索请求');
}, 300, true);
// 用户快速连续输入 'a' → 'ab' → 'abc'
// 实际输出仅一次:'发起搜索请求'(在输入 'a' 的瞬间)
注意:
- 它不会在停止输入后再次执行——这正是“立即执行防抖”与“节流”或“非立即防抖”的本质区别
- 适合场景:按钮点击防重复(点一下立刻响应,连点只算一次)、页面加载时初始化操作等
常见误区提醒
不要把“立即执行防抖”和“leading edge 节流”混淆:
- 节流保证固定间隔至少执行一次,有规律;防抖无论多频繁,只抓“首尾”之一(立即版抓首,普通版抓尾)
- 有些实现错误地在 setTimeout 中再次调用 func,会导致立即 + 延迟各执行一次,违背设计意图
- 记得保存 this 和 arguments,避免箭头函数导致上下文丢失(上面示例用 func.apply(this, arguments) 正确处理)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











