# 防抖(debounce)
# 什么是防抖?
当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。
# 实现思路
- 1.当触发事件时,执行setTimeout方法进行延迟执行。
- 2.在延迟执行时间段内再次触发事件,清除定时器,重新执行上步动作。
# 代码实现
/**
* @desc 函数防抖
* @param func 函数
* @param wait 延迟执行毫秒数
* @param immediate true 表立即执行,false 表非立即执行
*/
function debounce(fn, wait, immediate) {
let timer;
return function() {
let context = this;
let args = arguments;
if(immediate && !timer) {
fn.apply(context, args);
}
if(timer){
timer = clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(context, args);
timer = clearTimeout(timer);
},wait);
}
};
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 小例子
模拟远程数据:
{ "value": "烧饼" }
{ "value": "cocal" }
# 节流(throttle)
# 什么是节流
当持续触发事件时,保证一段时间内只调用一次事件处理函数.
# 实现思路
通过时间戳实现
- 1.保存当前时间
- 2.根据(当前时间 - 上次保存时间)是否大于设置dely时间,若大于执行,反之不执行fn
function throttle(fn, dely) {
let start = 0;
return function() {
let context = this;
let args = arguments;
let now = Date.now();
if(now - start > dely) {
fn.apply(context, args);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
通过定时器实现
- 1.首次执行调用定时器
- 2.再次执行会判断是否存在未执行完的定时器.若有,跳过不执行;反之,重新执行定时器
function throttle(fn, dely){
let timer;
return function() {
let context = this;
let args = arguments;
if(!timer) {
timer = setTimeout(() => {
timer = null;
fn.apply(context,args);
}, dely);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 小例子
控制台console查看不同
throttle处理: 0,0
未作处理: 0,0
← 闭包 bind、call、apply →