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

Commit

Permalink
fix: Support clearing the timeouts with numeric IDs
Browse files Browse the repository at this point in the history
Fixes #461
  • Loading branch information
platosha committed Oct 4, 2016
1 parent 63bca67 commit 9991b5c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
12 changes: 11 additions & 1 deletion lib/common/timers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,21 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam
setName += nameSuffix;
cancelName += nameSuffix;

var tasksByHandleId: Object = {};

function scheduleTask(task: Task) {
const data = <TimerOptions>task.data;
data.args[0] = task.invoke;
data.args[0] = function() {
task.invoke.apply(this, arguments);
delete tasksByHandleId[data.handleId];
};
data.handleId = setNative.apply(window, data.args);
tasksByHandleId[data.handleId] = task;
return task;
}

function clearTask(task: Task) {
delete tasksByHandleId[(<TimerOptions>task.data).handleId];
return clearNative((<TimerOptions>task.data).handleId);
}

Expand Down Expand Up @@ -60,6 +67,9 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam
clearNative =
patchMethod(window, cancelName, (delegate: Function) => function(self: any, args: any[]) {
var task: Task = args[0];
if (task && typeof task === 'number') {
task = tasksByHandleId[<number>task];
}
if (task && typeof task.type === 'string') {
if (task.cancelFn && task.data.isPeriodic || task.runCount === 0) {
// Do not cancel already canceled functions
Expand Down
21 changes: 21 additions & 0 deletions test/common/setTimeout.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,27 @@ describe('setTimeout', function() {
expect(typeof(cancelId.toString())).toBe('number');
});

it('should allow cancelation by numeric timeout Id', function (done) {
// Node returns complex object from setTimeout, ignore this test.
if (isNode) {
done();
return;
}

var testZone = Zone.current.fork(Zone['wtfZoneSpec']).fork({ name: 'TestZone' });
testZone.run(() => {
var spy = jasmine.createSpy('spy');
var task: Task = <any>setTimeout(spy, 0);
var cancelId: number = <any>task;
clearTimeout(0 + cancelId);
setTimeout(function () {
expect(spy).not.toHaveBeenCalled();
expect(task.runCount).toEqual(-1);
done();
});
});
});

it('should pass invalid values through', function() {
clearTimeout(null);
clearTimeout(<any>{});
Expand Down

0 comments on commit 9991b5c

Please sign in to comment.