6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
9
- import { Injectable , NgZone } from '@angular/core' ;
10
- import { from , Observable } from 'rxjs' ;
9
+ import { Injectable , NgZone , OnDestroy } from '@angular/core' ;
10
+ import { Subject } from 'rxjs' ;
11
+ import { take , takeUntil } from 'rxjs/operators' ;
12
+
13
+ /**
14
+ * @docs -private
15
+ */
16
+ export class _Schedule {
17
+ tasks : ( ( ) => unknown ) [ ] = [ ] ;
18
+ endTasks : ( ( ) => unknown ) [ ] = [ ] ;
19
+ }
11
20
12
21
/**
13
22
* Allows grouping up CSSDom mutations after the current execution context.
@@ -17,40 +26,55 @@ import {from, Observable} from 'rxjs';
17
26
* @docs -private
18
27
*/
19
28
@Injectable ( )
20
- export class _CoalescedStyleScheduler {
21
- private _currentSchedule : Observable < void > | null = null ;
29
+ export class _CoalescedStyleScheduler implements OnDestroy {
30
+ private _currentSchedule : _Schedule | null = null ;
31
+ private readonly _destroyed = new Subject < void > ( ) ;
22
32
23
33
constructor ( private readonly _ngZone : NgZone ) { }
24
34
25
35
/**
26
- * Schedules the specified task to run after the current microtask .
36
+ * Schedules the specified task to run at the end of the current VM turn .
27
37
*/
28
38
schedule ( task : ( ) => unknown ) : void {
29
39
this . _createScheduleIfNeeded ( ) ;
30
40
31
- this . _currentSchedule ! . subscribe ( task ) ;
41
+ this . _currentSchedule ! . tasks . push ( task ) ;
32
42
}
33
43
34
44
/**
35
- * Schedules the specified task to run after all scheduled tasks.
36
- * This is useful when measuring after style updates is required .
45
+ * Schedules the specified task to run after other scheduled tasks at the end of the current
46
+ * VM turn .
37
47
*/
38
48
scheduleEnd ( task : ( ) => unknown ) : void {
39
49
this . _createScheduleIfNeeded ( ) ;
40
50
41
- this . _currentSchedule ! . subscribe ( ( ) => {
42
- this . schedule ( task ) ;
43
- } ) ;
51
+ this . _currentSchedule ! . endTasks . push ( task ) ;
52
+ }
53
+
54
+ /** Prevent any further tasks from running. */
55
+ ngOnDestroy ( ) {
56
+ this . _destroyed . next ( ) ;
57
+ this . _destroyed . complete ( ) ;
44
58
}
45
59
46
60
private _createScheduleIfNeeded ( ) {
47
61
if ( this . _currentSchedule ) { return ; }
48
62
49
- this . _ngZone . runOutsideAngular ( ( ) => {
50
- this . _currentSchedule = from ( new Promise < void > ( ( resolve ) => {
51
- this . _currentSchedule = null ;
52
- resolve ( undefined ) ;
53
- } ) ) ;
63
+ this . _currentSchedule = new _Schedule ( ) ;
64
+
65
+ this . _ngZone . onStable . pipe (
66
+ take ( 1 ) ,
67
+ takeUntil ( this . _destroyed ) ,
68
+ ) . subscribe ( ( ) => {
69
+ const schedule = this . _currentSchedule ! ;
70
+ this . _currentSchedule = null ;
71
+
72
+ for ( const task of schedule . tasks ) {
73
+ task ( ) ;
74
+ }
75
+ for ( const task of schedule . endTasks ) {
76
+ task ( ) ;
77
+ }
54
78
} ) ;
55
79
}
56
80
}
0 commit comments