aboutsummaryrefslogtreecommitdiffstats
path: root/src/ng/timeout.js
diff options
context:
space:
mode:
authorIgor Minar2012-05-22 23:05:26 -0700
committerIgor Minar2012-05-23 15:00:56 -0700
commit4511d39cc748288df70bdc258f98a8f36652e683 (patch)
tree17402bb4910b12c4b1a38778309a62addd2c947f /src/ng/timeout.js
parent15b8f205bb4e9797608ce440075e5149db6e6d45 (diff)
downloadangular.js-4511d39cc748288df70bdc258f98a8f36652e683.tar.bz2
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
Diffstat (limited to 'src/ng/timeout.js')
-rw-r--r--src/ng/timeout.js87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/ng/timeout.js b/src/ng/timeout.js
new file mode 100644
index 00000000..ac92bf8c
--- /dev/null
+++ b/src/ng/timeout.js
@@ -0,0 +1,87 @@
+'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;
+ }];
+}