1 |
|
2 |
|
3 |
|
4 | export function throttle(
|
5 | fn: (...args: any[]) => any,
|
6 | wait = 250,
|
7 | ): (this: any, ...args: any[]) => any {
|
8 | let previous = 0;
|
9 | let timeout: number | null = null;
|
10 | let result: any;
|
11 | let storedContext: any;
|
12 | let storedArgs: any[];
|
13 |
|
14 | const later = (): void => {
|
15 | previous = Date.now();
|
16 | timeout = null;
|
17 | result = fn.apply(storedContext, storedArgs);
|
18 |
|
19 | if (!timeout) {
|
20 | storedContext = null;
|
21 | storedArgs = [];
|
22 | }
|
23 | };
|
24 |
|
25 | return function wrapper(this: any, ...args: any[]): any {
|
26 | const now = Date.now();
|
27 | const remaining = wait - (now - previous);
|
28 |
|
29 | storedContext = this;
|
30 | storedArgs = args;
|
31 |
|
32 | if (remaining <= 0 || remaining > wait) {
|
33 | if (timeout) {
|
34 | clearTimeout(timeout);
|
35 | timeout = null;
|
36 | }
|
37 |
|
38 | previous = now;
|
39 | result = fn.apply(storedContext, storedArgs);
|
40 |
|
41 | if (!timeout) {
|
42 | storedContext = null;
|
43 | storedArgs = [];
|
44 | }
|
45 | } else if (!timeout) {
|
46 | timeout = window.setTimeout(later, remaining);
|
47 | }
|
48 |
|
49 | return result;
|
50 | };
|
51 | }
|