防抖与节流——手动实现
构建小型防抖和节流工具。练习尾部触发与首部触发的变体,并了解何时选择哪一种
防抖与节流——手动实现 是 CoddyKit 上的免费 JavaScript Academy 课时。 这是第 2 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 JavaScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 JavaScript Academy 课程共包含 3 节课。
概览
目标:控制嘈杂的事件。
- 防抖:等待安静下来,然后运行一次
- 节流:每个时间间隔最多运行一次
- 前导调用与尾随调用
- 简短易读的辅助函数

防抖(尾随)
尾随防抖会在每个事件发生时重置计时器,并在事件平静下来后运行一次。
// Debounce (trailing): run once after events stop
function debounce(fn, wait) {
let t = null;
return function (...args) {
clearTimeout(t);
t = setTimeout(function () {
fn.apply(null, args);
}, wait);
};
}
// Simulate rapid events: only the last triggers the call
const debouncedLog = debounce(function (msg) {
console.log("debounced:", msg);
}, 10);
for (let i = 0; i < 5; i++) {
setTimeout(function () {
debouncedLog("final after bursts");
}, i * 3);
}

防抖(前导)
前导防抖会立即触发,然后在静默窗口结束前阻止重复触发。
// Debounce (leading): first call fires immediately, then ignore until quiet
function debounceLeading(fn, wait) {
let t = null;
return function (...args) {
if (t === null) {
fn.apply(null, args);
}
clearTimeout(t);
t = setTimeout(function () {
t = null;
}, wait);
};
}
// Demo: first call prints quickly; later bursts are ignored until quiet
const firstTap = debounceLeading(function (x) {
console.log("leading:", x);
}, 12);
for (let i = 0; i < 4; i++) {
setTimeout(function () {
firstTap("first-then-wait");
}, i * 3);
}

节流(前导)
节流会将调用限制为每个时间窗口一次,并丢弃多余调用。
// Throttle (leading): at most once per interval
function throttle(fn, wait) {
let last = 0;
return function (...args) {
const now = Date.now();
if (now - last >= wait) {
last = now;
fn.apply(null, args);
}
};
}
// Demo: many events, but prints at most once every 10ms
const throttled = throttle(function (n) {
console.log("throttled:", n);
}, 10);
for (let i = 0; i < 10; i++) {
setTimeout(function () {
throttled(i);
}, i * 2);
}

节流(尾随)
尾随节流确保您仍能在时间窗口结束时获得最新值。
// Throttle (trailing): schedule the last call within the window
function throttleTrailing(fn, wait) {
let last = 0;
let timer = null;
let queuedArgs = null;
function invoke(args) {
last = Date.now();
fn.apply(null, args);
}
return function (...args) {
const now = Date.now();
const remaining = wait - (now - last);
if (remaining <= 0) {
// Window passed: run now
clearTimeout(timer);
timer = null;
queuedArgs = null;
invoke(args);
} else {
// Queue the latest args to run at the end of the window
queuedArgs = args;
clearTimeout(timer);
timer = setTimeout(function () {
timer = null;
if (queuedArgs) {
invoke(queuedArgs);
queuedArgs = null;
}
}, remaining);
}
};
}
// Demo: last value in a burst is printed after the window
const trail = throttleTrailing(function (x) {
console.log("trail:", x);
}, 10);
for (let i = 0; i < 6; i++) {
setTimeout(function () {
trail("v" + i);
}, i * 3);
}

该使用哪一种
选择方式:
- 防抖:搜索输入、调整大小——在用户停止操作之后运行。
- 节流:滚动、拖动——将调用限制在稳定的节奏内。
- 前导用于即时反馈;尾随用于捕获最终值。

防抖与节流测验
快速检查:限制每个时间窗口内的调用次数。

回顾
回顾:您编写了尾随和前导防抖、简单的前导节流以及轻量的尾随节流。对于“用户停止操作后”选择防抖,对于“稳定的节奏”选择节流。

常见问题解答
「防抖与节流——手动实现」课时是免费的吗?
是的 — 「防抖与节流——手动实现」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 JavaScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 JavaScript Academy 课程共包含 3 节课。
「防抖与节流——手动实现」这节课中我会学到什么?
构建小型防抖和节流工具。练习尾部触发与首部触发的变体,并了解何时选择哪一种 你通过在浏览器中直接运行的动手代码来练习 JavaScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 JavaScript Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 JavaScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 3 节。
「防抖与节流——手动实现」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 JavaScript Academy 课中编写并运行代码吗?
能。每节 JavaScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。