@@ -26,72 +26,45 @@ type DebounceOptions = { maxWait?: number };
26
26
*/
27
27
export function debounce ( func : CallbackFunction , wait : number , options ?: DebounceOptions ) : DebouncedCallback {
28
28
let callbackReturnValue : unknown ;
29
- let timerId : ReturnType < typeof setTimeout > | undefined ;
30
- let lastCallTime : number | undefined ;
31
- let lastInvokeTime = 0 ;
32
29
33
- const maxWait = options && options . maxWait ? Math . max ( options . maxWait || 0 , wait ) : 0 ;
30
+ let timerId : ReturnType < typeof setTimeout > | undefined ;
31
+ let maxTimerId : ReturnType < typeof setTimeout > | undefined ;
34
32
35
- function invokeFunc ( time : number ) : unknown {
36
- timerId = undefined ;
37
-
38
- // Only invoke if we have `lastCallTime` which means `func` has been
39
- // debounced at least once.
40
- if ( lastCallTime !== undefined ) {
41
- lastInvokeTime = time ;
42
- callbackReturnValue = func ( ) ;
43
- }
33
+ const maxWait = options && options . maxWait ? Math . max ( options . maxWait , wait ) : 0 ;
44
34
35
+ function invokeFunc ( ) : unknown {
36
+ cancelTimers ( ) ;
37
+ callbackReturnValue = func ( ) ;
45
38
return callbackReturnValue ;
46
39
}
47
40
48
- function calcRemainingWait ( time : number ) : number {
49
- const timeSinceLastCall = time - ( lastCallTime || 0 ) ;
50
- const timeSinceLastInvoke = time - lastInvokeTime ;
51
- const remainingWait = wait - timeSinceLastCall ;
52
-
53
- return maxWait ? Math . min ( remainingWait , maxWait - timeSinceLastInvoke ) : remainingWait ;
41
+ function cancelTimers ( ) : void {
42
+ timerId !== undefined && clearTimeout ( timerId ) ;
43
+ maxTimerId !== undefined && clearTimeout ( maxTimerId ) ;
44
+ timerId = maxTimerId = undefined ;
54
45
}
55
46
56
- function shouldInvoke ( time : number ) : boolean {
57
- const timeSinceLastCall = time - ( lastCallTime || 0 ) ;
58
- const timeSinceLastInvoke = time - lastInvokeTime ;
59
-
60
- return timeSinceLastCall >= wait || ( Boolean ( maxWait ) && timeSinceLastInvoke >= maxWait ) ;
61
- }
62
-
63
- function timerExpired ( ) : void {
64
- const time = Date . now ( ) ;
65
- if ( shouldInvoke ( time ) ) {
66
- return void invokeFunc ( time ) ;
47
+ function flush ( ) : unknown {
48
+ if ( timerId !== undefined || maxTimerId !== undefined ) {
49
+ return invokeFunc ( ) ;
67
50
}
68
-
69
- // Restart the timer.
70
- timerId = setTimeout ( timerExpired , calcRemainingWait ( time ) ) ;
51
+ return callbackReturnValue ;
71
52
}
72
53
73
- function cancel ( ) : void {
74
- if ( timerId !== undefined ) {
54
+ function debounced ( ) : unknown {
55
+ if ( timerId ) {
75
56
clearTimeout ( timerId ) ;
76
57
}
77
- lastInvokeTime = 0 ;
78
- lastCallTime = timerId = undefined ;
79
- }
58
+ timerId = setTimeout ( invokeFunc , wait ) ;
80
59
81
- function flush ( ) : unknown {
82
- return timerId === undefined ? callbackReturnValue : invokeFunc ( Date . now ( ) ) ;
83
- }
84
-
85
- function debounced ( ) : unknown {
86
- lastCallTime = Date . now ( ) ;
87
- if ( timerId === undefined ) {
88
- lastInvokeTime = lastCallTime ;
89
- timerId = setTimeout ( timerExpired , wait ) ;
60
+ if ( maxWait && maxTimerId === undefined ) {
61
+ maxTimerId = setTimeout ( invokeFunc , maxWait ) ;
90
62
}
63
+
91
64
return callbackReturnValue ;
92
65
}
93
66
94
- debounced . cancel = cancel ;
67
+ debounced . cancel = cancelTimers ;
95
68
debounced . flush = flush ;
96
69
return debounced ;
97
70
}
0 commit comments