防抖和节流函数
在 JavaScript 中,防抖和节流 是两种常用的优化高频事件处理的技术,它们都能减少函数的执行频率,从而提升性能、避免不必要的计算或请求。以下是他们的详细说明,实现思路以及开发过程中遇到的使用场景。
一、防抖
防抖是指:在事件被频繁触发时,只有当事件停止触发一段时间后,才会执行一次回调函数。
换句话说,如果在设定的时间间隔内再次触发事件,则重新计时。
/*
* @param {function} fn - 需要防抖的函数
* @param {number} time - 多长时间执行一次
* @param {boolean} flag - 第一次是否执行
*/
function debounce(fn, time, flag) {
let timer;
return function(...args) {
// 在time时间段内重复执行,会清空之前的定时器,然后重新计时
timer && clearTimeout(timer);
if (flag && !timer) {
// flag为true 第一次默认执行
fn.apply(this, args);
}
timer = setTimeout(() => {
fn.apply(this, args);
}, time);
};
}
使用场景:
- 搜索框输入自动补全 / 搜索建议
用户每输入一个字符就发送请求会很浪费资源,可以等用户停止输入 300ms 后再发请求。 - 窗口大小改变(resize)后的布局调整
如果只是关心最终的尺寸,可以用防抖避免多次重绘。 - 表单验证(如邮箱格式校验)
用户输入过程中不立即校验,等用户停顿后再校验。 - 按钮点击防止重复提交
点击后禁用按钮一段时间,或者用防抖确保只提交一次。
二、节流
节流是指:在事件被频繁触发时,保证每隔固定时间至少执行一次回调函数。
即使事件持续触发,函数也会按照设定的最小时间间隔执行。
/*
* @param {function} fn - 需要防抖的函数
* @param {number} time - 多长时间执行一次
* @param {boolean} flag - 第一次是否执行
*/
function throttle(fn, time, flag) {
let timer;
return function(...args) {
// flag控制第一次是否立即执行
if (flag) {
fn.apply(this, args);
// 第一次执行完后,flag变为false;否则以后每次都会执行
flag = false;
}
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, args);
clearTimeout(timer);
// 每次执行完重置timer
timer = null;
}, time);
}
};
}
使用场景:
- 滚动事件(scroll)中加载更多内容 / 滚动日志上报
避免每滚动一像素就触发,而是每隔 200ms 执行一次。 - 鼠标移动(mousemove)跟踪位置
如拖拽、画图等场景,限制处理频率。 - 游戏中的技能冷却 / 射击频率控制
确保技能不会被无限连点。 - 定时数据采集或心跳上报
控制上报频率,避免过于频繁。
三、对比总结
| 特性 | 防抖 | 节流 |
|---|---|---|
| 触发时机 | 停止触发后延迟执行 | 固定间隔内至少执行一次 |
| 是否立即执行 | 可配置 | 可配置 |
| 适用场景 | 关注“最终结果”(如搜索、提交) | 关注“过程中的频率控制”(如滚动) |
| 函数调用次数 | 最终只执行一次 | 按时间间隔多次执行 |
一位 WordPress 评论者
您好,这是一条评论。若需要审核、编辑或删除评论,请访问仪表盘的评论界面。评论者头像来自 Gravatar。