节流函数通过时间戳+定时器双机制实现:首次触发立即执行,后续触发若间隔不足则用定时器延时执行并更新时间戳,确保高频场景下既及时响应又稳定输出。

节流函数的核心目标是:在高频触发场景下,让回调函数按固定间隔执行,既控制频率,又不丢失关键触发时机。用时间戳 + 定时器双机制配合,能兼顾响应及时性与执行稳定性,避免纯时间戳法的“卡顿感”和纯定时器法的“延迟累积”问题。
时间戳主导:立即响应 + 防止过快重复
每次触发时,先检查距离上一次执行是否已过设定间隔(如 100ms)。若满足,直接执行并更新时间戳;否则暂存本次调用意图,等待后续时机。
- 记录上一次成功执行的时间戳(lastTime),初始设为 0
- 当前触发时计算 now - lastTime >= delay,成立则立即执行并更新 lastTime = now
- 不成立说明太频繁,不执行,但需为后续留出“补救机会”——这就靠定时器兜底
定时器兜底:确保不会永久丢弃
仅靠时间戳会在连续快速触发时完全跳过中间调用,用户可能感觉“没反应”。引入定时器,在最后一次触发后延时执行一次,作为“保底输出”。
- 每次触发时,先清除已存在的待执行定时器(clearTimeout(timer))
- 然后设置新定时器:timer = setTimeout(() => { fn(); lastTime = Date.now(); }, delay)
- 注意:定时器内执行后,也要更新 lastTime,避免时间戳逻辑失效
组合逻辑:时间戳判断 + 定时器补偿
真正健壮的节流,是把两者融合:时间戳决定“能否立刻干”,定时器负责“如果一直不能立刻干,那就等一等再干”。关键在于只在必要时启动定时器,并且每次触发都重置它。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 初始化 lastTime = 0、timer = null
- 触发时:const now = Date.now()
- 若 now - lastTime >= delay → 立即执行,更新 lastTime
- 否则 → 清除旧定时器,新建一个延时 delay 的定时器(内部执行并更新 lastTime)
完整可运行示例
(去掉注释即可直接使用)
function throttle(fn, delay) {
let lastTime = 0;
let timer = null;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
fn.apply(this, args);
lastTime = now;
} else {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
lastTime = Date.now();
}, delay);
}
};
}这样实现后,鼠标连续拖拽、滚动监听等场景中,既能第一时间响应首次操作,又能在持续高频触发时稳定维持约每 delay 毫秒执行一次,无明显卡顿或堆积。

















