js防抖函数的实现原理

防抖动:将几次操作合并为一此操作进行。原理是维护一个计时器,规定在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
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

/*
*1.将几次操作合并为一此操作进行,只执行最后一次操作,若之前有操作则应该先取消
*2.在一定时间内只触发一次函数
*/


/**
* 函数防抖与节流
* @param fn :Function fn 函数
* @param delay :number delay 延迟执行毫秒数
* @param immediate:boolean immediate true 表示执行第一次调用
* false 表示执行最后一次调用
**/


debouce(func,delay,immediate){
var timer = null;
return function(){
var context = this;
var args = arguments;
if(timer) clearTimeout(timer);
if(immediate){
//根据距离上次触发操作的时间是否到达delay来决定是否要现在执行函数
var doNow = !timer;
//每一次都重新设置timer,就是要保证每一次执行的至少delay秒后才可以执行
timer = setTimeout(function(){
timer = null;
},delay);
//立即执行
if(doNow){
func.apply(context,args);
}
}else{
timer = setTimeout(function(){
func.apply(context,args);
},delay);
}
}
}



/**
* 函数防抖 (完全版)
* @param fn :Function fn 函数
* @param delay :number delay 延迟执行毫秒数
* @param immediate:boolean immediate true 表示执行第一次调用
* false 表示执行最后一次调用
* @param defaultReturn 仅当 immediate =true 时有效 表示消抖生效时的返回值
*
* 说明 immediate 为 true 时 返回的函数 第一次调用的返回值为 fn 的返回值 后续调用由于消抖的影响 会返回 defaultReturn
* immediate 为 false 返回的函数被调用永远返回 undefined
*/
public static debounce(fn: Function, delay: number, immediate: boolean = false, defaultReturn = null): any {
let timer = null;//定时器
let status = true;
if (immediate) {
return function (...args: any[]) {
clearTimeout(timer);
timer = setTimeout(() => status = true, delay);//每一次都重新设置timer,就是要保证每一次执行的至少delay秒后才可以执行
if (status) {
status = false;
return fn.call(this, ...args);
} else {
return defaultReturn
}
}
} else {
return function (...args: any[]) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => fn.call(this, ...args), delay)
}
}
}