节流核心是限定时间间隔内最多执行一次函数;时间戳版首次立即执行但丢弃末次,定时器版末次延迟执行但首次不立即;增强版可同时支持首尾执行。

节流(Throttle)的核心是:在指定时间间隔内,最多只执行一次函数,常用于高频触发场景(如滚动、鼠标移动),避免过度调用。
基于时间戳的节流实现
原理:记录上一次执行的时间戳,每次触发时对比当前时间与上次执行时间的差值。若超过设定间隔,则执行并更新时间戳;否则忽略。
- 适合“立即执行”场景(首次触发立刻执行)
- 不依赖定时器,逻辑轻量,无内存泄漏风险
- 注意:最后一次触发若未达间隔,将被丢弃
示例代码:
function throttleByTimestamp(func, delay) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
func.apply(this, args);
lastTime = now;
}
};
}基于定时器的节流实现
原理:使用 setTimeout 延迟执行,并在每次触发时清除前一个定时器,确保只有最后一次触发后的 delay 毫秒才执行(即“尾部执行”)。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
- 适合需要“稳定节奏”或“保证最终执行”的场景
- 需维护定时器 ID,注意及时清除防止内存泄漏
- 首次触发不会立刻执行,而是等待 delay 后执行
示例代码:
function throttleByTimer(func, delay) {
let timer = null;
return function(...args) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
timer = null;
}, delay);
};
}结合两者优势的增强版节流
实际项目中常需兼顾“首次立即执行”和“末次兜底执行”,可融合时间戳 + 定时器:
- 首次触发立即执行
- 后续触发在间隔内仅重置定时器
- 若停止触发,延迟执行最后一次(可选)
示例代码(带 leading & trailing 支持):
function throttle(func, delay, options = {}) {
const { leading = true, trailing = false } = options;
let lastTime = 0;
let timer = null;
<p>const run = () => {
func.apply(this, arguments);
};</p><p>return function(...args) {
const now = Date.now();</p><pre class="brush:php;toolbar:false;">if (!lastTime && leading) {
run();
lastTime = now;
return;
}
if (trailing && !timer) {
timer = setTimeout(() => {
run();
timer = null;
lastTime = 0;
}, delay);
return;
}
if (now - lastTime >= delay) {
run();
lastTime = now;
if (timer) {
clearTimeout(timer);
timer = null;
}
}}; }
使用建议与注意事项
- 明确业务需求:要“第一次就响应”还是“等稳了再响应”?选时间戳版或定时器版
- 注意 this 和参数传递:使用 func.apply(this, args) 或箭头函数 + 显式绑定
- 避免在闭包中长期持有 DOM 引用,防止内存泄漏(尤其定时器版)
- 测试时可用 console.timeLog 或 performance.now() 验证执行频率

















