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
| /**
| * Throttle decorator
| * @param {Function} fn
| * @param {Number} freq
| * @return {Function}
| */
| function throttle(fn, freq) {
| let timestamp = 0;
| let threshold = 1000 / freq;
| let lastArgs;
| let timer;
|
| const invoke = (args, now = Date.now()) => {
| timestamp = now;
| lastArgs = null;
| if (timer) {
| clearTimeout(timer);
| timer = null;
| }
| fn(...args);
| }
|
| const throttled = (...args) => {
| const now = Date.now();
| const passed = now - timestamp;
| if ( passed >= threshold) {
| invoke(args, now);
| } else {
| lastArgs = args;
| if (!timer) {
| timer = setTimeout(() => {
| timer = null;
| invoke(lastArgs)
| }, threshold - passed);
| }
| }
| }
|
| const flush = () => lastArgs && invoke(lastArgs);
|
| return [throttled, flush];
| }
|
| export default throttle;
|
|