js节流防抖实现思路
节流(Throttle)的实现思路
节流的核心思想是在一定时间内,无论事件触发多少次,只执行一次回调函数。适用于高频事件(如滚动、鼠标移动)的场景。
function throttle(fn, delay) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
fn.apply(this, args);
lastTime = now;
}
};
}
使用时间戳实现,第一次立即执行,后续每隔delay毫秒执行一次。适用于需要立即响应的场景。
function throttle(fn, delay) {
let timer = null;
return function(...args) {
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
}, delay);
}
};
}
使用定时器实现,第一次延迟执行,停止触发后会再执行一次。适用于需要保证最终执行的场景。

防抖(Debounce)的实现思路
防抖的核心思想是事件触发后等待一段时间再执行回调,若在等待期间再次触发则重新计时。适用于输入框搜索联想等场景。
function debounce(fn, delay) {
let timer = null;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
基础版实现,延迟执行,连续触发时重置延迟时间。

function debounce(fn, delay, immediate = false) {
let timer = null;
return function(...args) {
const shouldCallNow = immediate && !timer;
clearTimeout(timer);
timer = setTimeout(() => {
if (!immediate) fn.apply(this, args);
timer = null;
}, delay);
if (shouldCallNow) fn.apply(this, args);
};
}
增强版支持立即执行选项,第一次触发立即执行,后续触发需等待延迟结束。
两者区别与选择
节流保证周期内至少执行一次,适合连续高频触发但需要均匀响应的场景(如页面滚动)。
防抖在连续触发时不执行,直到停止后才执行,适合需要最终结果的场景(如搜索输入完成后的查询)。
实际应用示例
// 节流应用:滚动加载更多
window.addEventListener('scroll', throttle(loadMore, 500));
// 防抖应用:搜索框联想
input.addEventListener('input', debounce(fetchSuggestions, 300));
注意事项
高频场景中,使用requestAnimationFrame替代setTimeout可获得更流畅的性能表现。在React/Vue等框架中可直接使用useThrottle/useDebounce等Hook实现。





