高阶函数:函数节流
函数节流(Throttling) 是一种优化技术,用于限制函数的调用频率,确保在指定的时间间隔内只会执行一次函数。函数节流通常用于处理高频触发的事件,如滚动、调整窗口大小、按键等,以减少执行频率,降低资源消耗。
函数节流的工作原理
函数节流的核心思想是在给定的时间间隔内,只允许函数执行一次,超出的触发会被忽略。例如,如果设定的时间间隔为 100ms,那么无论在这段时间内触发多少次事件,函数都只会执行一次。
节流的实现方式
函数节流的常见实现方式是通过 setTimeout 来控制函数的执行节奏。下面是一个实现函数节流的示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function throttle(fn, delay) {
let lastExecutionTime = 0; // 记录上一次执行的时间
return function(...args) {
const now = Date.now(); // 获取当前时间
// 如果当前时间距离上次执行时间超过了设定的时间间隔
if (now - lastExecutionTime >= delay) {
lastExecutionTime = now; // 更新最后执行时间
fn.apply(this, args); // 执行目标函数
}
};
}
</script>
假设我们有一个滚动事件,并希望在用户滚动时,控制函数执行的频率,以减少不必要的重复调用:
1
2
3
window.addEventListener('scroll', throttle(() => {
console.log('Scroll event triggered');
}, 100)); // 设置100ms的时间间隔
在这个例子中,无论滚动事件多频繁触发,throttle 函数都会确保目标函数 console.log 至多每隔 100ms 执行一次。
优化点:使用 setTimeout 实现节流
除了上述实现方式,我们还可以使用 setTimeout 进行控制。如下:
1
2
3
4
5
6
7
8
9
10
11
12
function throttle(fn, delay) {
let timer = null;
return function(...args) {
if (!timer) { // 只有在没有定时器的情况下才设置新的定时器
timer = setTimeout(() => {
fn.apply(this, args); // 执行目标函数
timer = null; // 清空定时器标记
}, delay);
}
};
}
在该实现中,当触发事件时,如果 timer 不为空,则表示在指定时间间隔内不允许执行,fn 只有在 timer 过期后才能再次执行。和前面的实现类似,这种实现方式也可以很好地控制频繁触发的事件执行频率。
函数节流的使用场景
- 滚动事件:在页面滚动过程中可能会触发数百次事件,使用节流可以减少触发频率,例如:在页面滚动时执行懒加载或元素检测。
- 窗口调整:窗口大小调整时往往需要重新计算布局、更新内容,节流可以有效减少计算的频率。
- 按钮点击:例如点赞、收藏等按钮,节流可以防止用户多次点击造成重复请求。
函数节流与函数防抖的区别
- 函数节流:限制函数在规定的时间间隔内执行一次。即便多次触发,函数会每隔一段时间就执行一次。
- 函数防抖:在事件频繁触发的情况下,只在事件停止后的一段时间才执行函数。只要事件不断被触发,函数的执行就会被延迟。
总结
函数节流是优化高频事件执行的有效手段,特别适用于用户滚动、窗口调整等情况,通过在时间间隔内只执行一次函数,降低系统负担并提高性能。
本文由作者按照 CC BY 4.0 进行授权