mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
fix(core): execute timer trigger outside zone (#60392)
This should prevent defer timers from impacting app stability by executing them outside of the zone, similar to other defer triggers. fixes: #60373 PR Close #60392
This commit is contained in:
parent
24c5398f7d
commit
296aded9da
1 changed files with 10 additions and 6 deletions
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import {Injector, ɵɵdefineInjectable} from '../di';
|
||||
import {arrayInsert2, arraySplice} from '../util/array_utils';
|
||||
import {NgZone} from '../zone';
|
||||
|
||||
/**
|
||||
* Returns a function that captures a provided delay.
|
||||
|
|
@ -27,8 +28,9 @@ export function onTimer(delay: number) {
|
|||
*/
|
||||
export function scheduleTimerTrigger(delay: number, callback: VoidFunction, injector: Injector) {
|
||||
const scheduler = injector.get(TimerScheduler);
|
||||
const ngZone = injector.get(NgZone);
|
||||
const cleanupFn = () => scheduler.remove(callback);
|
||||
scheduler.add(delay, callback);
|
||||
scheduler.add(delay, callback, ngZone);
|
||||
return cleanupFn;
|
||||
}
|
||||
|
||||
|
|
@ -60,10 +62,10 @@ export class TimerScheduler {
|
|||
// as the shape of the `current` list.
|
||||
deferred: Array<number | VoidFunction> = [];
|
||||
|
||||
add(delay: number, callback: VoidFunction) {
|
||||
add(delay: number, callback: VoidFunction, ngZone: NgZone) {
|
||||
const target = this.executingCallbacks ? this.deferred : this.current;
|
||||
this.addToQueue(target, Date.now() + delay, callback);
|
||||
this.scheduleTimer();
|
||||
this.scheduleTimer(ngZone);
|
||||
}
|
||||
|
||||
remove(callback: VoidFunction) {
|
||||
|
|
@ -117,7 +119,7 @@ export class TimerScheduler {
|
|||
return index;
|
||||
}
|
||||
|
||||
private scheduleTimer() {
|
||||
private scheduleTimer(ngZone: NgZone) {
|
||||
const callback = () => {
|
||||
this.clearTimeout();
|
||||
|
||||
|
|
@ -170,7 +172,7 @@ export class TimerScheduler {
|
|||
}
|
||||
this.deferred.length = 0;
|
||||
}
|
||||
this.scheduleTimer();
|
||||
this.scheduleTimer(ngZone);
|
||||
};
|
||||
|
||||
// Avoid running timer callbacks more than once per
|
||||
|
|
@ -198,7 +200,9 @@ export class TimerScheduler {
|
|||
|
||||
const timeout = Math.max(invokeAt - now, FRAME_DURATION_MS);
|
||||
this.invokeTimerAt = invokeAt;
|
||||
this.timeoutId = setTimeout(callback, timeout) as unknown as number;
|
||||
this.timeoutId = ngZone.runOutsideAngular(() => {
|
||||
return setTimeout(() => ngZone.run(callback), timeout) as unknown as number;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue