fix(core): make sure onStable runs in the right zone (#18706)
Make sure the callbacks to the NgZone callbacks run in the right zone
with or without the rxjs Zone patch -
1ed83d08ac
.
PR Close #18706
This commit is contained in:
parent
079d884b6c
commit
713d7c2360
|
@ -455,17 +455,22 @@ export class ApplicationRef_ extends ApplicationRef {
|
||||||
});
|
});
|
||||||
|
|
||||||
const isStable = new Observable<boolean>((observer: Observer<boolean>) => {
|
const isStable = new Observable<boolean>((observer: Observer<boolean>) => {
|
||||||
const stableSub: Subscription = this._zone.onStable.subscribe(() => {
|
// Create the subscription to onStable outside the Angular Zone so that
|
||||||
NgZone.assertNotInAngularZone();
|
// the callback is run outside the Angular Zone.
|
||||||
|
let stableSub: Subscription;
|
||||||
|
this._zone.runOutsideAngular(() => {
|
||||||
|
stableSub = this._zone.onStable.subscribe(() => {
|
||||||
|
NgZone.assertNotInAngularZone();
|
||||||
|
|
||||||
// Check whether there are no pending macro/micro tasks in the next tick
|
// Check whether there are no pending macro/micro tasks in the next tick
|
||||||
// to allow for NgZone to update the state.
|
// to allow for NgZone to update the state.
|
||||||
scheduleMicroTask(() => {
|
scheduleMicroTask(() => {
|
||||||
if (!this._stable && !this._zone.hasPendingMacrotasks &&
|
if (!this._stable && !this._zone.hasPendingMacrotasks &&
|
||||||
!this._zone.hasPendingMicrotasks) {
|
!this._zone.hasPendingMicrotasks) {
|
||||||
this._stable = true;
|
this._stable = true;
|
||||||
observer.next(true);
|
observer.next(true);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -62,40 +62,44 @@ export class ComponentFixture<T> {
|
||||||
this.ngZone = ngZone;
|
this.ngZone = ngZone;
|
||||||
|
|
||||||
if (ngZone) {
|
if (ngZone) {
|
||||||
this._onUnstableSubscription =
|
// Create subscriptions outside the NgZone so that the callbacks run oustide
|
||||||
ngZone.onUnstable.subscribe({next: () => { this._isStable = false; }});
|
// of NgZone.
|
||||||
this._onMicrotaskEmptySubscription = ngZone.onMicrotaskEmpty.subscribe({
|
ngZone.runOutsideAngular(() => {
|
||||||
next: () => {
|
this._onUnstableSubscription =
|
||||||
if (this._autoDetect) {
|
ngZone.onUnstable.subscribe({next: () => { this._isStable = false; }});
|
||||||
// Do a change detection run with checkNoChanges set to true to check
|
this._onMicrotaskEmptySubscription = ngZone.onMicrotaskEmpty.subscribe({
|
||||||
// there are no changes on the second run.
|
next: () => {
|
||||||
this.detectChanges(true);
|
if (this._autoDetect) {
|
||||||
|
// Do a change detection run with checkNoChanges set to true to check
|
||||||
|
// there are no changes on the second run.
|
||||||
|
this.detectChanges(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
this._onStableSubscription = ngZone.onStable.subscribe({
|
||||||
this._onStableSubscription = ngZone.onStable.subscribe({
|
next: () => {
|
||||||
next: () => {
|
this._isStable = true;
|
||||||
this._isStable = true;
|
// Check whether there is a pending whenStable() completer to resolve.
|
||||||
// Check whether there is a pending whenStable() completer to resolve.
|
if (this._promise !== null) {
|
||||||
if (this._promise !== null) {
|
// If so check whether there are no pending macrotasks before resolving.
|
||||||
// If so check whether there are no pending macrotasks before resolving.
|
// Do this check in the next tick so that ngZone gets a chance to update the state of
|
||||||
// Do this check in the next tick so that ngZone gets a chance to update the state of
|
// pending macrotasks.
|
||||||
// pending macrotasks.
|
scheduleMicroTask(() => {
|
||||||
scheduleMicroTask(() => {
|
if (!ngZone.hasPendingMacrotasks) {
|
||||||
if (!ngZone.hasPendingMacrotasks) {
|
if (this._promise !== null) {
|
||||||
if (this._promise !== null) {
|
this._resolve !(true);
|
||||||
this._resolve !(true);
|
this._resolve = null;
|
||||||
this._resolve = null;
|
this._promise = null;
|
||||||
this._promise = null;
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
this._onErrorSubscription =
|
this._onErrorSubscription =
|
||||||
ngZone.onError.subscribe({next: (error: any) => { throw error; }});
|
ngZone.onError.subscribe({next: (error: any) => { throw error; }});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue