定义

  • 节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效

  • 防抖: n 秒后再执行该事件,若在 n 秒内被重复触发,则重新计时

是一种性能优化手段,比如浏览器的 scroll 等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地影响性能

实现

防抖

1
2
3
4
5
6
7
8
9
const debounce1: Function = (fun: Function, time: number) => {
let curTimer: any;
return function () {
clearTimeout(curTimer);
curTimer = setTimeout(() => {
fun();
}, time);
};
};

节流

使用时间戳方式实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 先执行函数再节流
* @param fun
* @param time
*/
const throttled: Function = (fun: Function, time: number) => {
let curTime = getTime();
return function () {
let newTime = getTime();
if (newTime - curTime >= time) {
fun();
curTime = getTime();
}
};
};

使用 setTimeout 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 先执行节流后执行函数
* @param fun
* @param time
*/
const throttled2: Function = (fun: Function, time: number) => {
let curTimer: any;
return function () {
if (!curTimer) {
curTimer = setTimeout(() => {
fun();
curTimer = null;
}, time);
}
};
};

以上都是最简单的实现,如果需要传参或者执行上下文,可以传入 this 和 arguments 对象,举例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
const throttled2: Function = (fun: Function, time: number) => {
let curTimer: any;
return function () {
let context = this;
let params = arguments;
if (!curTimer) {
curTimer = setTimeout(() => {
fun.apply(context, arguments);
curTimer = null;
}, time);
}
};
};

区别

相同点

  • 都是为了降低回调执行次数,优化性能

不同点

  • 节流是把一段连续高频操作降频,在时间段内均匀分割执行若干次。

  • 防抖是把一段连续高频操作合并,在时间段内只执行一次

应用场景

节流

  • 滚动加载,加载更多或滚到底部监听

  • 画布组件拖入时的事件回调

防抖

  • 搜索框搜索输入

  • 组件调整大小时,图需要重新自适应加载