防抖的核心是“等用户停下来再执行”,适合输入框搜索、窗口缩放等延迟响应场景,通过清除前次定时器、仅执行最后一次调用后的函数来实现。

防抖(Debounce)的核心是“等用户停下来再执行”,适合处理输入框搜索、窗口缩放等需要延迟响应的场景。它会忽略掉短时间内连续触发的多次调用,只保留最后一次触发后的执行。
debounce 函数的基本写法
一个轻量、可复用的 debounce 实现:
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
关键点:
• 每次调用都清除上一次定时器
• 只有最后一次调用后 delay 毫秒无新调用,才会真正执行 fn
• 使用 ...args 和 fn.apply(this, args) 保证 this 和参数正确传递
在输入框中绑定防抖搜索
以实时搜索为例,避免每按一个键就发请求:
const searchInput = document.getElementById('search');
const debouncedSearch = debounce((value) => {
fetch(`/api/search?q=${encodeURIComponent(value)}`)
.then(res => res.json())
.then(data => renderResults(data));
}, 300);
searchInput.addEventListener('input', (e) => {
debouncedSearch(e.target.value);
});
注意:
• 推荐用 input 事件(兼容中文输入法上屏)而非 keyup
• delay 设为 200–500ms 较合理:太短仍易触发,太长影响响应感
• 请求前可加 loading 状态或禁用按钮,提升用户体验
进阶:支持立即执行与取消
有些场景需要首次触发立刻执行(比如“搜索”按钮),之后再防抖,可用 leading 参数;也可提供手动取消能力:
function debounce(fn, delay, options = {}) {
const { leading = false, trailing = true } = options;
let timer, lastCall = 0;
const debounced = function (...args) {
const now = Date.now();
if (leading && now - lastCall > delay) {
fn.apply(this, args);
lastCall = now;
} else {
clearTimeout(timer);
timer = setTimeout(() => {
if (trailing) fn.apply(this, args);
lastCall = now;
}, delay);
}
};
debounced.cancel = () => clearTimeout(timer);
return debounced;
}
使用示例:
• debounce(fn, 300, { leading: true }):第一次输入立即查,后续按防抖走
• debounced.cancel():在组件卸载或切换页时调用,防止内存泄漏或状态错乱
常见误区提醒
• 不要在每次 render 中重新创建 debounce 函数(如 React 中写在函数体里),会导致事件监听器失效 —— 应用 useCallback 或定义在模块顶层
• 防抖不等于节流(throttle):节流是固定频率执行,防抖是“等停顿”
• 输入框内容为空时,可提前 return,避免空请求
• 后端也应做基础校验(如 q 参数长度、是否纯空格),前后端配合更健壮
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











