在浏览器的 滚动、搜索、窗口大小变化 等高频事件里,如果你还在 无差别触发函数,页面会卡顿、接口会爆炸、服务器会报警。
防抖(Debounce)和节流(Throttle)就是两把“节奏锁”——
- 防抖:等事件 完全停稳 后再执行一次;
- 节流:让事件在 固定间隔内 只执行一次。
掌握这两个函数,就能让 滚动加载更丝滑、搜索框更聪明、按钮更防误触。接下来,我们用 20 行代码 + 3 个场景,把它们彻底学会。
一、防抖(Debounce)
作用:事件触发后 n 秒 内不再触发,才执行函数。
版本 1:原生 setTimeout
function debounce(fn, delay) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
版本 2:带立即执行选项
function debounce(fn, delay, immediate = false) {
let timer = null;
return function (...args) {
if (immediate && !timer) fn.apply(this, args);
clearTimeout(timer);
timer = setTimeout(() => {
timer = null;
if (!immediate) fn.apply(this, args);
}, delay);
};
}
二、节流(Throttle)
作用:n 秒内 最多执行一次。
版本 1:时间戳
function throttle(fn, delay) {
let last = 0;
return function (...args) {
const now = Date.now();
if (now - last > delay) {
last = now;
fn.apply(this, args);
}
};
}
版本 2:定时器
function throttle(fn, delay) {
let timer = null;
return function (...args) {
if (!timer) {
timer = setTimeout(() => {
timer = null;
fn.apply(this, args);
}, delay);
}
};
}
三、速查表
场景 | 选择 |
---|---|
搜索框输入 | debounce(fn, 300) |
滚动加载 | throttle(fn, 200) |
窗口 resize | debounce(fn, 200, true) |
四、面试一句话
“防抖用于搜索框输入,节流用于滚动加载,核心都是 控制触发频率。”