3
3
const {
4
4
DateNow,
5
5
SafeMap,
6
- Symbol ,
6
+ SafeSet ,
7
7
globalThis,
8
8
} = primordials ;
9
9
10
+ const console = require ( 'console' )
11
+ const PriorityQueue = require ( 'internal/priority_queue' ) ;
12
+
13
+ function compareTimersLists ( a , b ) {
14
+ // console.log({ a, b})
15
+ const expiryDiff = a . runAt - b . runAt ;
16
+ if ( expiryDiff === 0 ) {
17
+ if ( a . id < b . id )
18
+ return - 1 ;
19
+ if ( a . id > b . id )
20
+ return 1 ;
21
+ }
22
+ return expiryDiff ;
23
+ }
24
+
25
+ function setPosition ( node , pos ) {
26
+ node . priorityQueuePosition = pos ;
27
+ }
10
28
class Timers {
29
+ #currentTimer = 1 ;
11
30
constructor ( ) {
12
- this . timers = new SafeMap ( ) ;
31
+ this . timers = new PriorityQueue ( compareTimersLists , setPosition ) ;
13
32
14
33
this . setTimeout = this . #createTimer. bind ( this , false ) ;
15
34
this . clearTimeout = this . #clearTimer. bind ( this ) ;
@@ -18,20 +37,20 @@ class Timers {
18
37
}
19
38
20
39
#createTimer( isInterval , callback , delay , ...args ) {
21
- const timerId = Symbol ( 'kTimerId' ) ;
22
- const timer = {
40
+ const timerId = this . #currentTimer ++ ;
41
+ this . timers . insert ( {
23
42
id : timerId ,
24
43
callback,
25
44
runAt : DateNow ( ) + delay ,
26
45
interval : isInterval ,
27
46
args,
28
- } ;
29
- this . timers . set ( timerId , timer ) ;
47
+ } ) ;
48
+
30
49
return timerId ;
31
50
}
32
51
33
- #clearTimer( timerId ) {
34
- this . timers . delete ( timerId ) ;
52
+ #clearTimer( position ) {
53
+ this . timers . removeAt ( position ) ;
35
54
}
36
55
37
56
}
@@ -49,25 +68,34 @@ class FakeTimers {
49
68
}
50
69
51
70
tick ( time = 0 ) {
52
-
71
+
53
72
// if (!this.isEnabled) {
54
73
// throw new Error('you should enable fakeTimers first by calling the .enable function');
55
74
// }
56
75
57
76
this . now += time ;
58
77
const timers = this . fakeTimers . timers ;
78
+ const alreadyProcessed = new SafeSet ( ) ;
79
+ while ( true ) {
80
+ const timer = timers . peek ( ) ;
81
+
82
+ if ( ! timer ) {
83
+ alreadyProcessed . clear ( ) ;
84
+ break ;
85
+ }
59
86
60
- for ( const timer of timers . values ( ) ) {
87
+ if ( alreadyProcessed . has ( timer ) ) break ;
88
+ alreadyProcessed . add ( timer ) ;
61
89
62
90
if ( ! ( this . now >= timer . runAt ) ) continue ;
63
-
64
91
timer . callback ( ...timer . args ) ;
65
- if ( timer . interval ) {
66
- timer . runAt = this . now + ( timer . runAt - this . now ) % timer . args [ 0 ] ;
67
- continue ;
68
- }
69
-
70
- timers . delete ( timer . id ) ;
92
+
93
+ // if (timer.interval) {
94
+ // timer.runAt = this.now + (timer.runAt - this.now) % timer.args[0];
95
+ // continue;
96
+ // }
97
+
98
+ timers . removeAt ( alreadyProcessed . size - 1 ) ;
71
99
}
72
100
}
73
101
@@ -89,6 +117,7 @@ class FakeTimers {
89
117
globalThis . setInterval = this . fakeTimers . setInterval ;
90
118
globalThis . clearInterval = this . fakeTimers . clearInterval ;
91
119
120
+ // this.#dispatchPendingTimers()
92
121
}
93
122
94
123
reset ( ) {
0 commit comments