0%

防抖(debounce)和节流(throttle)

防抖(debounce)和节流(throttle)

  1. 防抖:一段时间,多次点击,只保留最后一次事件。
  2. 节流:一段时间,多次点击,只执行第一次事件,之后的几次事件都会被过滤。

使用场景:

  1. 防抖:输入框连续输入,停下来之后再触发搜索。连续点击收藏按钮,只请求最后一次的状态
  2. 节流:防止按钮连续点击,如页面跳转事件,可能会打开多个页面。

其他说法:

  1. 防抖:连续触发事件时,只执行一次动作。每次触发事件,重新设定周期。
  2. 节流:一段时间内,触发多次事件,只执行一次动作。周期固定,动作定期执行,响应平滑。

代码实现

Flutter

写法一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class CommonUtil { 
static const _defaultDuration = 500;
static Timer? _timer;

// 实现:延时执行,持续触发时取消定时
static debounce(Function func, {durationTime = _defaultDuration}) {
_timer?.cancel();
_timer = new Timer(Duration(milliseconds: durationTime), () {
func.call();
_timer = null;
});
}

static int _lastTime = 0;

// 实现1:保存上一次点击时间,间隔时间内不重复触发
static throttle(Function func, {durationTime = _defaultDuration}) {
int currentTime = DateTime.now().millisecondsSinceEpoch;
if (currentTime - _lastTime > durationTime) {
func.call();
_lastTime = DateTime.now().millisecondsSinceEpoch;
}
}
}

写法二

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
class CommonUtil { 
static debounce(Function func, {durationTime = _defaultDuration}) {
Timer? timer;
Function target = () {
if (timer?.isActive ?? false) {
timer?.cancel();
}
timer = Timer(Duration(milliseconds: durationTime), () {
func.call();
});
};
return target;
}

// 实现2:添加enable标记,通过Future或者await等待上一次事件执行完成,再接收下一个事件。
static throttle(Future Function() func) {
bool enable = true;
Function target = () {
if (enable) {
enable = false;
func().then((_) => enable = true);
}
};
return target;
}
}

结语

参考文章:

  1. Android&RN&Flutter实战——防抖节流函数
  2. Flutter中的节流与防抖

欢迎关注我的其它发布渠道