mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-21 00:40:24 +00:00
The $interval service simplifies creating and testing recurring tasks. This service does not increment $browser's outstanding request count, which means that scenario tests and Protractor tests will not timeout when a site uses a polling function registered by $interval. Provides a workaround for #2402. For unit tests, repeated tasks can be controlled using ngMock$interval's tick(), tickNext(), and tickAll() functions.
90 lines
3 KiB
JavaScript
90 lines
3 KiB
JavaScript
'use strict';
|
|
|
|
|
|
function $IntervalProvider() {
|
|
this.$get = ['$rootScope', '$window', '$q',
|
|
function($rootScope, $window, $q) {
|
|
var intervals = {};
|
|
|
|
|
|
/**
|
|
* @ngdoc function
|
|
* @name ng.$interval
|
|
*
|
|
* @description
|
|
* Angular's wrapper for `window.setInterval`. The `fn` function is executed every `delay`
|
|
* milliseconds.
|
|
*
|
|
* The return value of registering an interval function is a promise. This promise will be
|
|
* notified upon each tick of the interval, and will be resolved after `count` iterations, or
|
|
* run indefinitely if `count` is not defined. The value of the notification will be the
|
|
* number of iterations that have run.
|
|
* To cancel an interval, call `$interval.cancel(promise)`.
|
|
*
|
|
* In tests you can use {@link ngMock.$interval#flush `$interval.flush(millis)`} to
|
|
* move forward by `millis` milliseconds and trigger any functions scheduled to run in that
|
|
* time.
|
|
*
|
|
* @param {function()} fn A function that should be called repeatedly.
|
|
* @param {number} delay Number of milliseconds between each function call.
|
|
* @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
|
|
* will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
|
|
* @returns {promise} A promise which will be notified on each iteration.
|
|
*/
|
|
function interval(fn, delay, count, invokeApply) {
|
|
var setInterval = $window.setInterval,
|
|
clearInterval = $window.clearInterval;
|
|
|
|
var deferred = $q.defer(),
|
|
promise = deferred.promise,
|
|
count = (isDefined(count)) ? count : 0,
|
|
iteration = 0,
|
|
skipApply = (isDefined(invokeApply) && !invokeApply);
|
|
|
|
promise.then(null, null, fn);
|
|
|
|
promise.$$intervalId = setInterval(function tick() {
|
|
deferred.notify(iteration++);
|
|
|
|
if (count > 0 && iteration >= count) {
|
|
deferred.resolve(iteration);
|
|
clearInterval(promise.$$intervalId);
|
|
delete intervals[promise.$$intervalId];
|
|
}
|
|
|
|
if (!skipApply) $rootScope.$apply();
|
|
|
|
}, delay);
|
|
|
|
intervals[promise.$$intervalId] = deferred;
|
|
|
|
return promise;
|
|
}
|
|
|
|
|
|
/**
|
|
* @ngdoc function
|
|
* @name ng.$interval#cancel
|
|
* @methodOf ng.$interval
|
|
*
|
|
* @description
|
|
* Cancels a task associated with the `promise`.
|
|
*
|
|
* @param {number} promise Promise returned by the `$interval` function.
|
|
* @returns {boolean} Returns `true` if the task was successfully canceled.
|
|
*/
|
|
interval.cancel = function(promise) {
|
|
if (promise && promise.$$intervalId in intervals) {
|
|
intervals[promise.$$intervalId].reject('canceled');
|
|
clearInterval(promise.$$intervalId);
|
|
delete intervals[promise.$$intervalId];
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
return interval;
|
|
}];
|
|
}
|