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
View
@@ -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;
View
@@ -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.