Files
angular.js/src/ng/timeout.js
Igor Minar 4511d39cc7 feat($timeout): add $timeout service that supersedes $defer
$timeout has a better name ($defer got often confused with something related to $q) and
is actually promise based with cancelation support.

With this commit the $defer service is deprecated and will be removed before 1.0.

Closes #704, #532
2012-05-23 15:00:56 -07:00

88 lines
2.9 KiB
JavaScript

'use strict';
function $TimeoutProvider() {
this.$get = ['$rootScope', '$browser', '$q', '$exceptionHandler',
function($rootScope, $browser, $q, $exceptionHandler) {
var deferreds = {};
/**
* @ngdoc function
* @name angular.module.ng.$timeout
* @requires $browser
*
* @description
* Angular's wrapper for `window.setTimeout`. The `fn` function is wrapped into a try/catch
* block and delegates any exceptions to
* {@link angular.module.ng.$exceptionHandler $exceptionHandler} service.
*
* The return value of registering a timeout function is a promise which will be resolved when
* the timeout is reached and the timeout function is executed.
*
* To cancel a the timeout request, call `$timeout.cancel(promise)`.
*
* In tests you can use {@link angular.module.ngMock.$timeout `$timeout.flush()`} to
* synchronously flush the queue of deferred functions.
*
* @param {function()} fn A function, who's execution should be delayed.
* @param {number=} [delay=0] Delay in milliseconds.
* @param {boolean=} [invokeApply=true] If set to false skips model dirty checking, otherwise
* will invoke `fn` within the {@link angular.module.ng.$rootScope.Scope#$apply $apply} block.
* @returns {*} Promise that will be resolved when the timeout is reached. The value this
* promise will be resolved with is the return value of the `fn` function.
*/
function timeout(fn, delay, invokeApply) {
var deferred = $q.defer(),
promise = deferred.promise,
skipApply = (isDefined(invokeApply) && !invokeApply),
timeoutId, cleanup;
timeoutId = $browser.defer(function() {
try {
deferred.resolve(fn());
} catch(e) {
deferred.reject(e);
$exceptionHandler(e);
}
if (!skipApply) $rootScope.$apply();
}, delay);
cleanup = function() {
delete deferreds[promise.$$timeoutId];
};
promise.$$timeoutId = timeoutId;
deferreds[timeoutId] = deferred;
promise.then(cleanup, cleanup);
return promise;
}
/**
* @ngdoc function
* @name angular.module.ng.$timeout#cancel
* @methodOf angular.module.ng.$timeout
*
* @description
* Cancels a task associated with the `promise`. As a result of this the promise will be
* resolved with a rejection.
*
* @param {Promise} promise Promise returned by the `$timeout` function.
* @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully
* canceled.
*/
timeout.cancel = function(promise) {
if (promise.$$timeoutId in deferreds) {
deferreds[promise.$$timeoutId].reject('canceled');
return $browser.defer.cancel(promise.$$timeoutId);
}
return false;
};
return timeout;
}];
}