Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit fea6d68

Browse files
platoshamhevery
authored andcommitted
fix: support clearing the timeouts with numeric IDs
Fixes #461
1 parent 63bca67 commit fea6d68

2 files changed

Lines changed: 30 additions & 2 deletions

File tree

lib/common/timers.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,21 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam
1919
setName += nameSuffix;
2020
cancelName += nameSuffix;
2121

22+
const tasksByHandleId: {[id: number]: Task} = {};
23+
2224
function scheduleTask(task: Task) {
2325
const data = <TimerOptions>task.data;
24-
data.args[0] = task.invoke;
26+
data.args[0] = function() {
27+
task.invoke.apply(this, arguments);
28+
delete tasksByHandleId[data.handleId];
29+
};
2530
data.handleId = setNative.apply(window, data.args);
31+
tasksByHandleId[data.handleId] = task;
2632
return task;
2733
}
2834

2935
function clearTask(task: Task) {
36+
delete tasksByHandleId[(<TimerOptions>task.data).handleId];
3037
return clearNative((<TimerOptions>task.data).handleId);
3138
}
3239

@@ -59,7 +66,7 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam
5966

6067
clearNative =
6168
patchMethod(window, cancelName, (delegate: Function) => function(self: any, args: any[]) {
62-
var task: Task = args[0];
69+
var task: Task = typeof args[0] === 'number' ? tasksByHandleId[args[0]] : args[0];
6370
if (task && typeof task.type === 'string') {
6471
if (task.cancelFn && task.data.isPeriodic || task.runCount === 0) {
6572
// Do not cancel already canceled functions

test/common/setTimeout.spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,27 @@ describe('setTimeout', function() {
102102
expect(typeof(cancelId.toString())).toBe('number');
103103
});
104104

105+
it('should allow cancelation by numeric timeout Id', function (done) {
106+
// Node returns complex object from setTimeout, ignore this test.
107+
if (isNode) {
108+
done();
109+
return;
110+
}
111+
112+
const testZone = Zone.current.fork(Zone['wtfZoneSpec']).fork({ name: 'TestZone' });
113+
testZone.run(() => {
114+
const spy = jasmine.createSpy('spy');
115+
const task: Task = <any>setTimeout(spy, 0);
116+
const cancelId: number = <any>task;
117+
clearTimeout(0 + cancelId);
118+
setTimeout(function () {
119+
expect(spy).not.toHaveBeenCalled();
120+
expect(task.runCount).toEqual(-1);
121+
done();
122+
}, 1);
123+
});
124+
});
125+
105126
it('should pass invalid values through', function() {
106127
clearTimeout(null);
107128
clearTimeout(<any>{});

0 commit comments

Comments
 (0)