|
14 | 14 | args: any[]; |
15 | 15 | delay: number; |
16 | 16 | isPeriodic: boolean; |
| 17 | + isRequestAnimationFrame: boolean; |
17 | 18 | } |
18 | 19 |
|
19 | 20 | interface MicroTaskScheduledFunction { |
|
35 | 36 |
|
36 | 37 | scheduleFunction( |
37 | 38 | cb: Function, delay: number, args: any[] = [], isPeriodic: boolean = false, |
38 | | - id: number = -1): number { |
| 39 | + isRequestAnimationFrame: boolean = false, id: number = -1): number { |
39 | 40 | let currentId: number = id < 0 ? this.nextId++ : id; |
40 | 41 | let endTime = this._currentTime + delay; |
41 | 42 |
|
|
46 | 47 | func: cb, |
47 | 48 | args: args, |
48 | 49 | delay: delay, |
49 | | - isPeriodic: isPeriodic |
| 50 | + isPeriodic: isPeriodic, |
| 51 | + isRequestAnimationFrame: isRequestAnimationFrame |
50 | 52 | }; |
51 | 53 | let i = 0; |
52 | 54 | for (; i < this._schedulerQueue.length; i++) { |
|
100 | 102 | ' tasks. Does your code use a polling timeout?'); |
101 | 103 | } |
102 | 104 | // If the only remaining tasks are periodic, finish flushing. |
103 | | - if (!(this._schedulerQueue.filter(task => !task.isPeriodic).length)) { |
| 105 | + if (!(this._schedulerQueue.filter(task => !task.isPeriodic && !task.isRequestAnimationFrame) |
| 106 | + .length)) { |
104 | 107 | break; |
105 | 108 | } |
106 | 109 | let current = this._schedulerQueue.shift(); |
|
131 | 134 | pendingPeriodicTimers: number[] = []; |
132 | 135 | pendingTimers: number[] = []; |
133 | 136 |
|
134 | | - constructor(namePrefix: string) { |
| 137 | + constructor(namePrefix: string, private trackPendingRequestAnimationFrame = false) { |
135 | 138 | this.name = 'fakeAsyncTestZone for ' + namePrefix; |
136 | 139 | } |
137 | 140 |
|
|
174 | 177 | return () => { |
175 | 178 | // Requeue the timer callback if it's not been canceled. |
176 | 179 | if (this.pendingPeriodicTimers.indexOf(id) !== -1) { |
177 | | - this._scheduler.scheduleFunction(fn, interval, args, true, id); |
| 180 | + this._scheduler.scheduleFunction(fn, interval, args, true, false, id); |
178 | 181 | } |
179 | 182 | }; |
180 | 183 | } |
|
185 | 188 | }; |
186 | 189 | } |
187 | 190 |
|
188 | | - private _setTimeout(fn: Function, delay: number, args: any[]): number { |
| 191 | + private _setTimeout(fn: Function, delay: number, args: any[], isTimer = true): number { |
189 | 192 | let removeTimerFn = this._dequeueTimer(this._scheduler.nextId); |
190 | 193 | // Queue the callback and dequeue the timer on success and error. |
191 | 194 | let cb = this._fnAndFlush(fn, {onSuccess: removeTimerFn, onError: removeTimerFn}); |
192 | | - let id = this._scheduler.scheduleFunction(cb, delay, args); |
193 | | - this.pendingTimers.push(id); |
| 195 | + let id = this._scheduler.scheduleFunction(cb, delay, args, false, !isTimer); |
| 196 | + if (isTimer) { |
| 197 | + this.pendingTimers.push(id); |
| 198 | + } |
194 | 199 | return id; |
195 | 200 | } |
196 | 201 |
|
|
302 | 307 | case 'mozRequestAnimationFrame': |
303 | 308 | // Simulate a requestAnimationFrame by using a setTimeout with 16 ms. |
304 | 309 | // (60 frames per second) |
305 | | - task.data['handleId'] = this._setTimeout(task.invoke, 16, (task.data as any)['args']); |
| 310 | + task.data['handleId'] = this._setTimeout( |
| 311 | + task.invoke, 16, (task.data as any)['args'], |
| 312 | + this.trackPendingRequestAnimationFrame); |
306 | 313 | break; |
307 | 314 | default: |
308 | 315 | throw new Error('Unknown macroTask scheduled in fake async test: ' + task.source); |
|
0 commit comments