Skip to content
Permalink
Browse files

feat($interval): allow function to calculate the delay for each itera…

…tion.
  • Loading branch information
amyboyd committed Jul 27, 2014
1 parent 9025113 commit 86fb3b0a124f6fd11740e389383142c7ed2ecbe2
Showing with 51 additions and 4 deletions.
  1. +18 −4 src/ng/interval.js
  2. +33 −0 test/ng/intervalSpec.js
@@ -34,7 +34,9 @@ function $IntervalProvider() {
* </div>
*
* @param {function()} fn A function that should be called repeatedly.
* @param {number} delay Number of milliseconds between each function call.
* @param {number|function()} delay Number of milliseconds between each function call. If this
* is a function, it will be called with the one argument - the iteration number - and must
* return a number.
* @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat
* indefinitely.
* @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
@@ -137,13 +139,15 @@ function $IntervalProvider() {
iteration = 0,
skipApply = (isDefined(invokeApply) && !invokeApply),
deferred = (skipApply ? $$q : $q).defer(),
promise = deferred.promise;
promise = deferred.promise,
isDelayFunction = angular.isFunction(delay),
delayNumber = Number(isDelayFunction ? delay(iteration) : delay);

count = isDefined(count) ? count : 0;

promise.then(null, null, fn);

promise.$$intervalId = setInterval(function tick() {
var tick = function() {
deferred.notify(iteration++);

if (count > 0 && iteration >= count) {
@@ -154,7 +158,17 @@ function $IntervalProvider() {

if (!skipApply) $rootScope.$apply();

}, delay);
if (isDelayFunction) {
var newDelayNumber = Number(delay(iteration));
if (newDelayNumber !== delayNumber) {
delayNumber = newDelayNumber;
clearInterval(promise.$$intervalId);
promise.$$intervalId = setInterval(tick, newDelayNumber);
}
}
};

promise.$$intervalId = setInterval(tick, delayNumber);

intervals[promise.$$intervalId] = deferred;

@@ -129,6 +129,39 @@ describe('$interval', function() {
}));



it('should allow you to specify the delay time with a function', inject(function($interval, $window) {
var counter = 0;
$interval(
function() { counter++; },
function(iteration) { return iteration + 5; }
);

expect(counter).toBe(0);

$window.flush(4);
expect(counter).toBe(0);

$window.flush(1);
expect(counter).toBe(1);

$window.flush(1);
expect(counter).toBe(1);

$window.flush(5);
expect(counter).toBe(2);

$window.flush(7);
expect(counter).toBe(3);

$window.flush(7);
expect(counter).toBe(3);

$window.flush(1);
expect(counter).toBe(4);
}));


it('should allow you to specify a number of iterations', inject(function($interval, $window) {
var counter = 0;
$interval(function() {counter++;}, 1000, 2);

0 comments on commit 86fb3b0

Please sign in to comment.
You can’t perform that action at this time.