节流函数需支持“尾部执行”以确保最后一次操作不丢失:首次触发立即执行,后续用定时器延迟执行并清除重设,配合trailing配置缓存末次参数,且通过cancel方法防止内存泄漏。

节流函数默认只保证“固定间隔执行”,容易在快速滚动或拖拽结束时漏掉最后一次状态更新。要确保最后一次操作不丢失,关键不是单纯限制频率,而是让节流逻辑具备“兜底执行”能力——即在事件停止触发后,仍能补上最后一次未执行的调用。
用定时器实现“尾部执行”
这是最常用也最有效的方案:首次触发立即执行,后续触发不立即执行,而是用 setTimeout 延迟安排一次执行;如果期间再次触发,就清除旧定时器、重设新的,确保最终只在“静止”后执行一次。
- 闭包保存 timer ID,每次调用前先 clearTimeout,再 set 新定时器
- 定时器回调中执行目标函数,并将 timer 置为 null,表示可接受下一轮触发
- 这样即使用户猛滚到底部又立刻松手,最后一次 scrollTop 值仍会被捕获并处理
支持 trailing 配置的增强版
更灵活的做法是把“是否补执行最后一次”做成可配置项(trailing: true),同时兼容 leading(首次立即执行):
- 用闭包维护 lastTime(记录上次执行时间)、timer(当前待执行定时器)、pendingArgs 和 pendingThis
- 当 trailing 为 true 且本次未满足立即执行条件时,缓存参数和 this,等 delay 结束后统一执行
- 避免因快速连续触发导致末次参数被覆盖,确保状态完整
注意 cancel 的配合使用
在组件卸载或监听器移除前,主动调用 throttle 函数的 cancel 方法,能防止定时器在组件销毁后仍尝试执行,造成内存泄漏或报错,间接保障最后一次逻辑的可控性:
立即学习“Java免费学习笔记(深入)”;
- 在 throttle 返回函数上挂载 cancel 方法,内部 clearTimeout 并清空 timer
- React 中可在 useEffect 清理函数里调用;Vue 中在 beforeUnmount 里调用
- cancel 不仅是清理手段,也是让“最后一次执行”真正落地前的最后保险


















