Reschedule all functions for a tick before executing any

- This allows any function run during a tick to cancel any other in the
  same tick.

Fixes #708
This commit is contained in:
slackersoft
2014-12-05 08:01:34 -08:00
parent a4faa80be4
commit 4d5f27d359
3 changed files with 57 additions and 8 deletions

View File

@@ -1244,6 +1244,12 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
scheduledFn.runAtMillis + scheduledFn.millis);
}
function forEachFunction(funcsToRun, callback) {
for (var i = 0; i < funcsToRun.length; ++i) {
callback(funcsToRun[i]);
}
}
function runScheduledFunctions(endTime) {
if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {
return;
@@ -1255,15 +1261,15 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
var funcsToRun = scheduledFunctions[currentTime];
delete scheduledFunctions[currentTime];
for (var i = 0; i < funcsToRun.length; ++i) {
var funcToRun = funcsToRun[i];
forEachFunction(funcsToRun, function(funcToRun) {
if (funcToRun.recurring) {
reschedule(funcToRun);
}
});
forEachFunction(funcsToRun, function(funcToRun) {
funcToRun.funcToCall.apply(null, funcToRun.params || []);
}
});
} while (scheduledLookup.length > 0 &&
// checking first if we're out of time prevents setTimeout(0)
// scheduled in a funcToRun from forcing an extra iteration

View File

@@ -255,5 +255,42 @@ describe("DelayedFunctionScheduler", function() {
scheduler.tick(10);
});
it("removes functions during a tick that runs the function", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
fnDelay = 10,
timeoutKey;
timeoutKey = scheduler.scheduleFunction(fn, fnDelay, [], true);
scheduler.scheduleFunction(function () {
scheduler.removeFunctionWithId(timeoutKey);
}, 2 * fnDelay);
expect(fn).not.toHaveBeenCalled();
scheduler.tick(3 * fnDelay);
expect(fn).toHaveBeenCalled();
expect(fn.calls.count()).toBe(2);
});
it("removes functions during the first tick that runs the function", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
fnDelay = 10,
timeoutKey;
timeoutKey = scheduler.scheduleFunction(fn, fnDelay, [], true);
scheduler.scheduleFunction(function () {
scheduler.removeFunctionWithId(timeoutKey);
}, fnDelay);
expect(fn).not.toHaveBeenCalled();
scheduler.tick(3 * fnDelay);
expect(fn).toHaveBeenCalled();
expect(fn.calls.count()).toBe(1);
});
});

View File

@@ -114,6 +114,12 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
scheduledFn.runAtMillis + scheduledFn.millis);
}
function forEachFunction(funcsToRun, callback) {
for (var i = 0; i < funcsToRun.length; ++i) {
callback(funcsToRun[i]);
}
}
function runScheduledFunctions(endTime) {
if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {
return;
@@ -125,15 +131,15 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
var funcsToRun = scheduledFunctions[currentTime];
delete scheduledFunctions[currentTime];
for (var i = 0; i < funcsToRun.length; ++i) {
var funcToRun = funcsToRun[i];
forEachFunction(funcsToRun, function(funcToRun) {
if (funcToRun.recurring) {
reschedule(funcToRun);
}
});
forEachFunction(funcsToRun, function(funcToRun) {
funcToRun.funcToCall.apply(null, funcToRun.params || []);
}
});
} while (scheduledLookup.length > 0 &&
// checking first if we're out of time prevents setTimeout(0)
// scheduled in a funcToRun from forcing an extra iteration