函数防抖和节流
Chao 工程师

函数防抖

节流或是防抖:限制函数的执行次数

概念

节流(throttle):减少一段时间的触发频率

防抖(debounce):通过setTimeout 的方式,在一定的时间间隔内,将多次触发变成一次触发

应用场景

节流:滚动加载更多、搜索框搜的索联想功能、高频点击、表单重复提交……

防抖:搜索框搜索输入,并在输入完以后自动搜索、手机号,邮箱验证输入检测、窗口大小 resize 变化后,再重新渲染。

区别

节流:事件被触发、n秒内只执行一次事件处理函数

防抖:n秒内触发事件,就重新计时,事件处理函数的程序将永远不被执行

场景

按钮的点击事件

节流:设置1s的时间,每1s内,只会执行一次。

防抖:设置1s的时间,操作间隔大于1s才会执行,否则不会。

节流代码:

1
2
3
4
5
6
7
8
9
10
function throttle(fn, delay) {
let begin = 0;
return function () {
let cur = new Date().getTime();
if (cur - begin > delay) { // 连续点击在节流时间内,则不执行
fn.apply(this, arguments);
begin = cur;
}
}
}

防抖代码:

第一次不执行:
1
2
3
4
5
6
7
8
9
10
11
12
function debounce(fn, delay) {
let t = null;
return function () {
if (t) {
clearTimeout(t);
}

t = setTimeout(() => {
fn.apply(this, arguments);
}, delay)
}
}
第一次执行:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function debounce(fn, delay) {
let t;
return function () {

if (t) {
clearTimeout(t);
}

if (!t) { // 第一次t肯定为空
fn.apply(this, arguments);
}

t = setTimeout(() => {
t = null; // delay 间隔后重置,再次点击时又是第一次
}, delay)
}
}
通过开关控制第一次是否执行:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function debounce(fn, delay, triggleNow) {
let t;
return function () {

if (t) {
clearTimeout(t);
}

if (triggleNow) {
if (!t) { // 第一次点击
fn.apply(this, arguments);
}

t = setTimeout(() => {
t = null; // delay 间隔后重置,再次点击时又是第一次
}, delay)

} else {
t = setTimeout(() => {
fn.apply(this, arguments);
}, delay)
}
}
}
 Comments