实现一个防抖-节流
# 实现一个防抖-节流
// 防抖
function debounce(fn, delay) {
let timer = null
let handle = function() {
if (timer) {
clearTimeout(timer)
}
timer = setTImeout(() => {
fn()
}, delay)
}
return handle
}
// 原函数带参数
function debounce(fn, delay) {
let timer = null
let handle = function() {
if (timer) {
clearTimeout(timer)
}
// 获取this和arguments
let _this = this
let _arguments = arguments
timer = setTImeout(() => {
fn.apply(_this, _arguments)
}, delay)
}
return handle
}
// 带取消功能
function debounce(fn, delay) {
let timer = null
let handle = function() {
if (timer) {
clearTimeout(timer)
}
let _this = this
let _arguments = arguments
timer = setTImeout(() => {
fn.apply(_this, _arguments)
}, delay)
}
// 取消处理
handle.cancel = function() {
if (timer) {
clearTimeout(timer)
}
}
return handle
}
// 第一次立即执行
function debounce(fn, delay, leading) {
let timer = null
let handle = function() {
if (timer) {
clearTimeout(timer)
}
let _this = this
let _arguments = arguments
if (leading) {
// 通过一个变量记录是否立即执行
let isInvoke = false
if(!timer) {
fn.apply(_this, _arguments)
isInvoke = true
}
timer = setTimeout(() => {
timer = null
if (!isInvoke) {
fn.apply(_this, _arguments)
}
}, delay);
} else {
timer = setTImeout(() => {
fn.apply(_this, _arguments)
}, delay)
}
}
return handle
}
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
76
77
78
79
80
81
82
83
84
85
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
76
77
78
79
80
81
82
83
84
85
不管事件触发频率多高, 一定在事件触发 n 秒后才执行
/**
* @param {function} event
* @param {number} time
*/
function debounce(event, time) {
let timer = null
return function (...args) {
clearTimeout(timer)
timer = setTimeout(() => {
event.apply(this, args)
}, time)
}
}
// 立即执行一次,再等后面事件触发后等待 n 秒执行,用 flag 标示是否执行
/**
* @param {function} event
* @param {number} time
* @param {boolean} flag
*/
function debounce(event, time, flag) {
let timer = null
return function (...args) {
clearTimeout(timer)
if (flag && !timer) event.apply(this, args)
timer = setTimeout(() => {
event.apply(this, args)
}, time)
}
}
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
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
不管事件触发频率多高,只在单位时间内执行一次
节流:固定时间内 就只执行一次
// # 时间戳实现: 第一次事件肯定触发,最后一次不会触发
/**
* @param {function} event
* @param {number} time
*/
function throttle(event, time) {
let pre = 0
return function (...args) {
if (Date.now() - pre > time) {
pre = Date.now()
event.apply(this, args)
}
}
}
// # 定时器实现: 第一次事件不会触发,最后一次一定触发
/**
* @param {function} event
* @param {number} time
*/
function throttle(event, time) {
let timer = null
return function (...args) {
if (!timer) {
timer = setTimeout(() => {
timer = null
event.apply(this, args)
}, time)
}
}
}
// # 结合版: 定时器和时间戳的结合版,也相当于节流和防抖的结合版,第一次和最后一次都会触发
/**
* @param {function} event
* @param {number} time
*/
function throttle(event, time) {
let pre = 0
let timer = null
return function (...args) {
if (Date.now() - pre > time) {
clearTimeout(timer)
timer = null
pre = Date.now()
event.apply(this, args)
} else if (!timer) {
timer = setTimeout(() => {
event.apply(this, args)
}, time)
}
}
}
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
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