JavaScript实现防抖、节流

在开发过程中往往会遇到这类需求,某些界面或按钮在弱网情况下点击没有反应,用户就会疯狂的点击,后台就源源不断的向服务器发送请求,用户体验贼差。
为了解决在这一问题,就会想到能不能在一定时间内无论用户点击多少次,只触发一次请求。
这时就会考虑到节流防抖,那么什么是节流和防抖呢,怎么来实现?

  • 防抖:单位时间内,频繁触发事件,只执行最后一次

思路:利用定时器,每次触发先清除定时器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function debounce(fn, wait) {
var timer = null;
return function () {
var context = this;
args = [...arguments];
// 如果此时存在定时器的话,则取消之前定时器重新计时
if (timer) {
clearTimeout(timer);
timer = null;
}

// 设置定时器,使事件间隔指定时间后执行;
timer = setTimeout(() => {
fn.apply(context, args);
}, 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// 节流时间戳
function throttle(fn,delay){
var preTime = Date.now();
return function(){
var context = this
args = [...arguments];

// 如果两次时间间隔超过了指定时间,则执行函数
if(nowTime - preTime >=delay){
preTime = Date.now();
return fn.apply(context,args)
}
}
}
// 节流-定时器
function throttleTime(fun,wait){
let timeout = null;
return function(){
let context = this;
let args = [...arguments]
if(!timeout){
timeout = setTimeout(() => {
fun.apply(context,args)
timeout = null;
}, wait);
}
}
}
// 节流-时间戳+定时器
function throttleTimeAndTimer(fun,wait){
let preTime = Date.now();
let timeout = null;
return function(){
let context = this;
let args = [...arguments]
let nowTime = Date.now();
if(nowTime - preTime >= wait){
if(timeout){
clearTimeout(timeout)
timeout = null;
}
preTime = Date.now();
fun.apply(context,args)
}else if(!timeout){
timeout = setTimeout(() => {
fun.apply(context,args)
timeout = null;
}, wait);
}
}
}

免责声明:本文只是作者的个人观点,不代表网站立场。 转载请注明出处。