@@ -14,6 +14,7 @@ class TimerExecutor {
1414 private intervalHandle : ReturnType < typeof setTimeout > | undefined ;
1515 private isFirstTime : boolean = true ;
1616 private isPendingExecution : boolean = false ;
17+ private waitingExecutionToFinish : boolean = false ;
1718 private canExecute : boolean = false ;
1819
1920 private delay ?: number ;
@@ -22,10 +23,26 @@ class TimerExecutor {
2223
2324 private callback ?: ( ) => void ;
2425
25- setCallback ( callback : ( ) => void , canExecute : boolean ) : void {
26+ setCallback ( callback : ( ) => void , newCanExecute : boolean ) : void {
2627 this . callback = callback ;
27- this . canExecute = canExecute ;
2828
29+ if ( this . waitingExecutionToFinish && this . canExecute && ! newCanExecute ) {
30+ // this means we just executed the command, and canExecute went from true to false
31+ // we should not do anything, only wait for the flag to go back to true
32+ this . canExecute = newCanExecute ;
33+ return ;
34+ }
35+
36+ if ( this . waitingExecutionToFinish && ! this . canExecute && newCanExecute ) {
37+ // this means action completed successfully
38+ // we can start a new timer
39+ this . waitingExecutionToFinish = false ;
40+ this . canExecute = newCanExecute ;
41+ this . next ( ) ;
42+ return ;
43+ }
44+
45+ this . canExecute = newCanExecute ;
2946 this . trigger ( ) ;
3047 }
3148
@@ -34,15 +51,18 @@ class TimerExecutor {
3451 this . interval = interval ;
3552 this . repeat = repeat ;
3653
37- this . next ( ) ;
54+ if ( this . isFirstTime ) {
55+ // kickstart the timer for the first time
56+ this . next ( ) ;
57+ }
3858 }
3959
4060 get isReady ( ) : boolean {
4161 return this . delay !== undefined && ( ! this . repeat || this . interval !== undefined ) ;
4262 }
4363
4464 next ( ) : void {
45- if ( ! this . isReady ) {
65+ if ( ! this . isReady || this . waitingExecutionToFinish ) {
4666 return ;
4767 }
4868
@@ -56,9 +76,8 @@ class TimerExecutor {
5676 this . intervalHandle = setTimeout (
5777 ( ) => {
5878 this . isPendingExecution = true ;
59- this . trigger ( ) ;
6079 this . isFirstTime = false ;
61- this . next ( ) ;
80+ this . trigger ( ) ;
6281 } ,
6382 this . isFirstTime ? this . delay : this . interval
6483 ) ;
@@ -67,6 +86,7 @@ class TimerExecutor {
6786 trigger ( ) : void {
6887 if ( this . isPendingExecution && this . canExecute ) {
6988 this . isPendingExecution = false ;
89+ this . waitingExecutionToFinish = true ;
7090 this . callback ?.( ) ;
7191 }
7292 }
@@ -77,6 +97,9 @@ class TimerExecutor {
7797 this . delay = undefined ;
7898 this . interval = undefined ;
7999 this . repeat = false ;
100+ this . isFirstTime = true ;
101+ this . isPendingExecution = false ;
102+ this . waitingExecutionToFinish = false ;
80103 }
81104}
82105
@@ -97,11 +120,4 @@ export function useOnLoadTimer(props: UseOnLoadTimerProps): void {
97120 timerExecutor . stop ( ) ;
98121 } ;
99122 } , [ timerExecutor , delay , interval , repeat ] ) ;
100-
101- // cleanup
102- useEffect ( ( ) => {
103- return ( ) => {
104- timerExecutor . stop ( ) ;
105- } ;
106- } , [ timerExecutor ] ) ;
107123}
0 commit comments