防抖与节流

(2 mins to read)

用于优化高频率执行代码。比如在浏览器中scroll等事件会频繁触发,导致不断地调用该时间上的回调函数,降低前端的性能。

Debounce

仅在一个时间周期结束时才执行,如果重复触发,则重新计时。

1
2
3
4
5
6
7
8
9
10
11
12
13
function debounce(func, wait) {
let timeout;

return function () {
let context = this; // 保存this指向
let args = arguments; // 拿到event对象

clearTimeout(timeout)
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}

应用场景:

  • 窗口大小resize,只需在调整完毕后,计算一次最终的窗口大小,执行渲染即可。
  • 网站提交订单,用户双击按钮,防抖可以确保只提交一次订单。

此外防抖也是一种保障数据稳定的手段,可以过滤掉无效或不稳定的数据,从而降低数据误报的影响。

在硬件开关中,信号可能发生跳变,因此通常需要对信号的值进一步做一个特殊的处理,比如

  • 只有在连续一段时间内都是1(从上升沿,即0变1开始计时),才为1,降低抖动的影响
  • 每次变成1,就保持一段时间,一直返回1,用于延长或截断信号的发送

switch-debound

Throttle

在一个时间周期内,仅在第一次触发时执行。

1
2
3
4
5
6
7
8
9
10
11
function throttled(fn, delay = 500) {
let timer = null
return function (...args) {
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, args)
timer = null
}, delay);
}
}
}

应用场景:

  • 滚动加载,每隔一段时间执行一次。

滤波

顾名思义,就是过滤掉一些特定的波(去掉不想要的噪声,保留想要的)。

卡尔曼滤波,又叫二次型估计,能从先前一系列包含噪声的观测量中,提供对系统当前状态的相对准确且平滑的估计。之所以称为滤波,就是因为它会过滤掉之前观测量中的噪声和不确定性。

前面提到的防抖也可以算一种消抖滤波,在嵌入式开发信号处理中会用。