节流函数时间戳实现首次立即执行:初始化lastTime为0,每次触发时用Date.now()减lastTime,≥delay则执行并更新lastTime;首次必执行,后续受控,无定时器且轻量。

节流函数中用时间戳实现“首次立即执行”,核心思路是:**记录上一次执行的时间戳,本次触发时,先立即执行,再更新时间戳;后续在冷却期内的调用被忽略,直到时间间隔过去才允许下一次执行。**
关键逻辑:用时间戳判断是否过了节流间隔
每次触发函数时,获取当前时间戳(Date.now() 或 +new Date()),与上次执行的时间戳比较:
- 如果当前时间 - 上次执行时间 ≥ 设定的延迟(delay),就立即执行,并更新“上次执行时间”为当前时间;
- 否则,不执行,直接返回。
实现代码(首次立即执行版)
下面是一个简洁可靠的实现:
function throttle(func, delay) {
let lastTime = 0;
return function (...args) {
const now = Date.now();
if (now - lastTime >= delay) {
func.apply(this, args);
lastTime = now;
}
};
}✅ 特点说明:
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
-
首次调用必执行:因为
lastTime初始为 0,now - 0一定 ≥delay(只要 delay 是正数),所以第一次一定进 if 并执行; - 后续受控执行:只有距离上次执行已满 delay 毫秒,才会再次执行;
- 无定时器、无状态堆积:纯时间戳比对,轻量且无内存泄漏风险。
和定时器节流的区别
常见定时器节流(如用 setTimeout + clearTimeout)默认是“首次触发后延迟执行”,要改造成首次立即执行需额外处理(比如先执行再设定时器)。而时间戳方案天然支持首次立即执行,逻辑更直白、副作用更少。
注意事项
-
时间精度足够:浏览器中
Date.now()毫秒级精度,满足常规节流需求(如 scroll、resize); -
注意 this 和参数传递:上面示例用了
func.apply(this, args),确保正确绑定上下文和透传参数; - 不适用于需要“最后一次必须执行”的场景:该方案只保证“至少间隔 delay 才执行”,不缓存或补发延迟期内的最后一次调用(那是防抖做的事)。
不复杂但容易忽略的是:把 lastTime 初始化为 0,而不是 Date.now() 或 null——前者让首次必然通过判断,后者需额外判空逻辑,反而增加复杂度。










