两者各自的保证
防抖回答“调用方停止调用后再执行”。每次新调用都会重置计时器。搜索框在每次按键时触发,应该等用户停顿后只查询一次,而不是每个字符查询一次。
节流回答“每个时间间隔最多执行一次”。滚动处理器即使持续滚动,也可以每 100ms 读取一次 scrollY。
function debounce(fn, wait) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), wait);
};
}
function throttle(fn, interval) {
let last = 0;
return (...args) => {
const now = Date.now();
if (now - last >= interval) {
last = now;
fn(...args);
}
};
}
何时使用哪一种
当中间值没有价值时使用防抖:搜索建议、自动保存、输入后的校验。当中间值有意义时使用节流:滚动联动动画、分析采样、拖拽坐标。
与限流相比,防抖和节流是客户端的人机交互控制;服务端限流保护共享容量,而防抖与节流保护浏览器和下游 API 免受不必要的工作。
常见陷阱
最常见的错误是在渲染或事件注册中重新创建包装函数,导致每次调用都重置计时器。应只创建一次并复用。第二个问题是忘记尾调用:纯 leading-edge 节流可能丢掉最后一个值,而这往往是用户最关心的值。