forked from yeyan1996/practical-javascript
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththrottle.js
84 lines (79 loc) · 2.42 KB
/
throttle.js
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
/**
* @description 函数节流
* @param {Function} func -需要函数节流的函数
* @param {Number} time -延迟时间
* @param {Options} options -配置项
* @return {Function} -经过节流处理的函数
**/
/**
* @typedef {Object} Options -配置项
* @property {Boolean} leading -开始是否需要额外触发一次
* @property {Boolean} trailing -结束后是否需要额外触发一次
* @property {this} context -上下文
**/
const throttle = (func, time = 17, options = {
// leading 和 trailing 无法同时为 false
leading: true,
trailing: false,
context: null
}) => {
let previous = new Date(0).getTime()
let timer;
const _throttle = function (...args) {
let now = new Date().getTime();
if (!options.leading) {
if (timer) return
timer = setTimeout(() => {
timer = null
func.apply(options.context, args)
}, time)
} else if (now - previous > time) {
func.apply(options.context, args)
previous = now
} else if (options.trailing) {
clearTimeout(timer)
timer = setTimeout(() => {
func.apply(options.context, args)
}, time)
}
};
// 闭包返回取消函数
_throttle.cancel = () => {
previous = 0;
clearTimeout(timer);
timer = null
};
return _throttle
};
//使用Proxy实现函数节流
function proxy(func, time, options = {
// leading 和 trailing 无法同时为 false
leading: false,
trailing: true,
context: null
}) {
let timer;
let previous = new Date(0).getTime();
let handler = {
apply(target, _, args) {
// 和闭包实现核心逻辑相同
let now = new Date().getTime();
if (!options.leading) {
if (timer) return;
timer = setTimeout(() => {
timer = null;
Reflect.apply(func, options.context, args)
}, time)
} else if (now - previous > time) {
Reflect.apply(func, options.context, args)
previous = now
} else if (options.trailing) {
clearTimeout(timer)
timer = setTimeout(() => {
Reflect.apply(func, options.context, args)
}, time)
}
}
};
return new Proxy(func, handler)
}