节流函数应封装为可配参数的组件,支持wait(执行间隔)、leading(首次是否立即执行)等选项,常用时间戳+开关模式实现;增强版还可支持trailing(末次补执行)和cancel方法;健壮封装需正确处理this、arguments及Promise返回值。

节流函数封装成可配参数的组件,核心是让调用者能灵活控制执行间隔、是否立即执行、以及函数上下文和参数传递。不是只写一个固定逻辑,而是提供明确选项,适应不同业务场景。
支持 wait 和 leading 参数的节流封装
最常用的是时间戳 + 开关模式:用上次执行时间判断是否该执行,再配合 leading(首次是否立即执行)控制行为。
- wait:必填,毫秒数,表示最小执行间隔
- leading:布尔值,默认 false;设为 true 时,第一次触发立刻执行,后续按间隔执行
示例实现:
function throttle(fn, wait, leading = false) {
let lastTime = 0;
let timer = null;
<p>return function(...args) {
const now = Date.now();</p><pre class='brush:php;toolbar:false;'>if (leading && !lastTime) {
fn.apply(this, args);
lastTime = now;
return;
}
if (now - lastTime >= wait) {
fn.apply(this, args);
lastTime = now;
} else if (!timer && !leading) {
timer = setTimeout(() => {
fn.apply(this, args);
lastTime = Date.now();
timer = null;
}, wait - (now - lastTime));
}}; }
支持 trailing 和 cancel 方法的增强版
有些场景需要取消待执行的节流(比如组件卸载),或确保最后一次触发也执行(trailing)。这时可返回带方法的对象:
立即学习“Java免费学习笔记(深入)”;
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 返回函数本身,同时挂载 cancel 方法清空定时器
- trailing:设为 true 时,在 wait 结束后补一次执行(即使中间没再触发)
示例:
function throttle(fn, wait, options = {}) {
const { leading = false, trailing = false } = options;
let lastTime = 0;
let timer = null;
<p>const throttled = function(...args) {
const now = Date.now();</p><pre class='brush:php;toolbar:false;'>if (leading && !lastTime) {
fn.apply(this, args);
lastTime = now;
return;
}
if (now - lastTime >= wait) {
fn.apply(this, args);
lastTime = now;
} else if (!timer && !leading) {
timer = setTimeout(() => {
if (trailing) fn.apply(this, args);
lastTime = Date.now();
timer = null;
}, wait - (now - lastTime));
}};
throttled.cancel = () => { if (timer) { clearTimeout(timer); timer = null; } };
return throttled; }
兼容 this、arguments 和 Promise 的健壮封装
实际项目中,fn 可能是箭头函数、需要绑定 this,或返回 Promise。封装时需注意:
- 用 ...args 接收全部参数,避免 arguments 对象丢失
- 用 fn.apply(this, args) 保证上下文正确
- 如需链式调用或 await,可在执行后返回 fn 的返回值(但注意节流本身不改变返回语义)
推荐写法(简洁实用):
function throttle(fn, wait) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= wait) {
lastTime = now;
return fn.apply(this, args);
}
};
}这个版本轻量、无副作用、this 和参数都可靠,适合大多数按钮点击、滚动监听等场景。

















