Skip to content

Commit f19b36f

Browse files
Platonndylhunn
authored andcommitted
fix(zone.js): in TaskTrackingZoneSpec track a periodic task until it is cancelled (#45391)
Before this change, the macrotask for `setInterval(callback, ms)` was no longer tracked by `TaskTrackingZoneSpec` after the `callback` was invoked for the first time. Now the periodic macrotask is tracked until it is cancelled, e.g. `clearInterval(id)`. BREAKING CHANGE: in TaskTrackingZoneSpec track a periodic task until it is cancelled The breaking change is scoped only to the plugin `zone.js/plugins/task-tracking`. If you used `TaskTrackingZoneSpec` and checked the pending macroTasks e.g. using `(this.ngZone as any)._inner ._parent._properties.TaskTrackingZone.getTasksFor('macroTask')`, then its behavior slightly changed for periodic macrotasks. For example, previously the `setInterval` macrotask was no longer tracked after its callback was executed for the first time. Now it's tracked until the task is explicitly cancelled, e.g with `clearInterval(id)`. fixes 45350 PR Close #45391
1 parent c7bcc1b commit f19b36f

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

packages/zone.js/lib/zone-spec/task-tracking.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class TaskTrackingZoneSpec implements ZoneSpec {
5858
onInvokeTask(
5959
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task,
6060
applyThis: any, applyArgs: any): any {
61-
if (task.type === 'eventTask')
61+
if (task.type === 'eventTask' || task.data?.isPeriodic)
6262
return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs);
6363
const tasks = this.getTasksFor(task.type);
6464
for (let i = 0; i < tasks.length; i++) {

packages/zone.js/test/zone-spec/task-tracking.spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,25 @@ describe('TaskTrackingZone', function() {
7575
expect((taskTrackingZoneSpec!.macroTasks[0] as any)['creationLocation']).toBeTruthy();
7676
});
7777
});
78+
79+
it('should track periodic task until it is canceled', (done) => {
80+
taskTrackingZone.run(() => {
81+
const intervalCallback = jasmine.createSpy('intervalCallback');
82+
const interval = setInterval(intervalCallback, 1);
83+
84+
expect(intervalCallback).not.toHaveBeenCalled();
85+
expect(taskTrackingZoneSpec!.macroTasks.length).toBe(1);
86+
expect(taskTrackingZoneSpec!.macroTasks[0].source).toBe('setInterval');
87+
88+
setTimeout(() => {
89+
expect(intervalCallback).toHaveBeenCalled();
90+
expect(taskTrackingZoneSpec!.macroTasks.length).toBe(1);
91+
expect(taskTrackingZoneSpec!.macroTasks[0].source).toBe('setInterval');
92+
93+
clearInterval(interval);
94+
expect(taskTrackingZoneSpec!.macroTasks.length).toBe(0);
95+
done();
96+
}, 2);
97+
});
98+
});
7899
});

0 commit comments

Comments
 (0)