防抖函数每次触发时清除旧定时器并重设新倒计时,实现“最后一次触发后延迟执行”;标准行为非额外功能,核心是clearTimeout(timeout)置于setTimeout之前。

防抖函数在等待期间自动延长,本质是每次触发时重置定时器——这不是“额外功能”,而是标准防抖(debounce)的默认行为。关键在于:**每次调用都清除前一个定时器,再启动新的倒计时**。
核心逻辑:覆盖旧定时器
防抖不是固定等 300ms 后执行,而是“最后一次触发后,再等 300ms 才执行”。只要在这 300ms 内又触发一次,就清掉上一次的倒计时,重新开始 300ms 计时。
- 用户连续输入 5 次,间隔均小于设定延迟 → 只有最后一次输入后的延迟结束时执行一次
- 第 3 次触发时,第 1、2 次的定时器已被 clearTimeout 清除,不再生效
- 不需要手动“延长”,清除 + 重设 = 自动延长效果
基础实现(带 immediate 可选)
以下是一个常见且清晰的手写版本:
function debounce(func, wait, immediate = false) {
let timeout = null;
return function(...args) {
const later = () => {
timeout = null;
if (!immediate) func.apply(this, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(this, args);
};
}
✅ 关键点:clearTimeout(timeout) 必须放在 setTimeout 之前 —— 这保证了每次调用都先清除旧任务。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
立即学习“Java免费学习笔记(深入)”;
常见误写:忘记清除或位置错误
错误示例(不会自动延长):
// ❌ 错误:没清定时器 → 多次触发会累积多个 setTimeout
function badDebounce(func, wait) {
return function() {
setTimeout(() => func.apply(this, arguments), wait); // 每次都新建,不清理
};
}
⚠️ 这样写会导致多次执行,完全失去“防抖”意义,更谈不上自动延长。
实际使用建议
- 把防抖函数作为事件处理器的包装层,例如:
input.addEventListener('input', debounce(handleSearch, 300)) - 需要立即执行首次调用?传
true给immediate参数(常用于按钮点击防重复提交) - 注意 this 和参数传递:用
...args和func.apply(this, args)确保上下文正确 - 如需取消防抖(比如组件卸载),可返回一个 cancel 方法,内部保存并暴露 clearTimeout 调用

















