12.函数防抖,函数节流
一、函数防抖
1、什么是函数防抖
事件触发后,等待一段时间(延迟)。若在等待期间再次触发事件,则重新计时。
只有最后一次触发生效,之前的触发均被取消。
2、函数防抖代码实现
- immediate = false,则每次在 delay 后执行一次函数,首次不会执行
- immediate = true,则首次触发立即执行,之后在 delay 后执行一次函数
function debounce(func, delay, immediate = false) {
// 闭包保存的定时器标识
let timer;
// 返回防抖处理后的函数(接收任意参数)
return function (...args) {
const that = this;
const callNow = immediate && !timer; // 判断是否满足"立即执行"条件
clearTimeout(timer); // 每次触发都先清除之前的定时器
timer = setTimeout(() => {
timer = null;
// 若非立即执行模式,则在延迟后调用目标函数
if (!immediate) {
// 确保正确的 this 和参数传递
func.apply(that, args);
}
}, delay);
// 如果满足立即执行条件,则立即调用目标函数
if (callNow) func.apply(that, args);
};
}
二、函数节流
1、什么是函数节流
无论事件触发多频繁,固定时间间隔内只执行一次函数。
稀释函数的执行频率,保证周期性调用。
2、函数节流代码实现
// 时间戳版本(立即执行首次)
function throttle(func, delay) {
let lastTime = 0;
return function (...args) {
const now = Date.now();
if (now - lastTime >= delay) {
func.apply(this, args);
lastTime = now;
}
};
}
// 定时器版本(延迟执行首次)
function throttle(func, delay) {
let timer = null;
return function (...args) {
if (!timer) {
timer = setTimeout(() => {
func.apply(this, args);
timer = null;
}, delay);
}
};
}
三、应用场景
场景 | 技术方案 | 原因 |
---|---|---|
列表页滚动加载更多 | 节流 | 需要周期性触发(如每 500ms ),保证加载节奏,避免遗漏中间滚动位置。 |
搜索框输入联想 | 防抖 | 用户停止输入后才请求结果,避免无效中间请求(如输入“abc” 时只查“abc” )。 |
按钮防重复提交 | 防抖(立即执行) 或 节流 | 根据需求选择:立即执行首次点击,屏蔽后续点击(防抖 + immediate=true )。固定间隔内只允许提交一次(节流)。 |
窗口大小调整布局计算 | 防抖 | 调整结束后计算一次布局,避免频繁重绘。 |
游戏角色移动控制 | 节流 | 限制高频按键响应频率,保证操作流畅性(如每 100ms 响应一次方向键)。 |