下图是 普通事件/防抖事件/节流事件 执行的示例图,可以对函数防抖以及函数节流有一个初步了解。

注意:示例图中的防抖事件/节流事件有 delay: 50ms 的延迟调用,示例图中仅表示普通事件进行防抖/节流处理后可以触发的对应事件,而非执行的时间点

函数防抖和函数节流

函数防抖(Debounce)

定义:函数防抖就是指触发事件后一定时间内函数只能执行一次,如果在这段时间内再次触发事件,则会重新计算函数执行时间

举例:乘坐公交车时,司机需要等待最后一个人进入后才能关门。每次进入一个人,司机就会多等待几秒再关门。

实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// immediate 首次是否立即执行
function debounce(func, delay = 500, immediate = false) {
let timer = null;
return function() {
if (timer) clearTimeout(timer);
if (immediate) {
let applyNow = !timer;
timer = setTimeout(function() {
timer = null;
}, delay);
if (applyNow) func.apply(this, arguments);
} else {
timer = setTimeout(function() {
func.apply(this, arguments);
timer = null;
}, delay);
}
}
}

// 外部调用
function doSomething() {
// doing something
}
const debounceEvent = debounce(doSomething, 100);
debounceEvent();

应用场景

  1. 表单内容输入验证
  2. 部分搜索功能的模糊查询结果

函数节流(Throttle)

定义:函数节流就是指连续触发事件在一定时间内(周期)只执行一次,函数节流会稀释函数执行的频率

举例:乘坐地铁过闸机时,每个人进入后 3 秒后门关闭,等待下一个人进入。

实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// immediate 首次是否立即执行
function throttle(func, delay, immediate = false) {
let timer = null;
return function() {
if (timer) return ;
if (immediate) {
let applyNow = !timer;
timer = setTimeout(function() {
timer = null;
}, delay);
if (applyNow) func.apply(this, arguments);
} else {
timer = setTimeout(function() {
func.apply(this, arguments);
timer = null;
}, delay);
}
}
}

// 外部调用
function doSomething() {
// doing something
}
const throttleEvent = throttle(doSomething, 100);
throttleEvent();

应用场景

  1. 鼠标的跟随动画
  2. scrollresize 等高频事件

联系与区别

  • 相同点

    函数防抖与函数节流都是用来控制某个函数在一定事件内触发的次数,降低事件触发频率,从而提高性能避免资源浪费

  • 不同点

    函数防抖仅触发最后一次事件,其余事件被屏蔽;而函数节流保留第一次触发的事件,其余事件被屏蔽。

参考资料

__END__