Permalink
Browse files

feat($timeout): allow `fn` to be an optional parameter

Closes #9176
Close #9723
  • Loading branch information...
1 parent 034fade commit 5a60302389162c6ef45f311c1aaa65a00d538c66 @vasileorza vasileorza committed with petebacondarwin Oct 21, 2014
Showing with 39 additions and 5 deletions.
  1. +13 −3 src/ng/timeout.js
  2. +26 −2 test/ng/timeoutSpec.js
View
@@ -4,6 +4,7 @@
function $TimeoutProvider() {
this.$get = ['$rootScope', '$browser', '$q', '$$q', '$exceptionHandler',
function($rootScope, $browser, $q, $$q, $exceptionHandler) {
+
var deferreds = {};
@@ -16,15 +17,18 @@ function $TimeoutProvider() {
* block and delegates any exceptions to
* {@link 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.
+ * The return value of calling `$timeout` is a promise, which will be resolved when
+ * the delay has passed and the timeout function, if provided, is executed.
*
* To cancel a timeout request, call `$timeout.cancel(promise)`.
*
* In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to
* synchronously flush the queue of deferred functions.
*
- * @param {function()} fn A function, whose execution should be delayed.
+ * If you only want a promise that will be resolved after some specified delay
+ * then you can call `$timeout` without the `fn` function.
+ *
+ * @param {function()=} fn A function, whose 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 ng.$rootScope.Scope#$apply $apply} block.
@@ -33,6 +37,12 @@ function $TimeoutProvider() {
*
*/
function timeout(fn, delay, invokeApply) {
+ if (!isFunction(fn)) {
+ invokeApply = delay;
+ delay = fn;
+ fn = noop;
+ }
+
var skipApply = (isDefined(invokeApply) && !invokeApply),
deferred = (skipApply ? $$q : $q).defer(),
promise = deferred.promise,
@@ -105,6 +105,25 @@ describe('$timeout', function() {
}));
+ it('should allow the `fn` parameter to be optional', inject(function($timeout, log) {
+
+ $timeout().then(function(value) { log('promise success: ' + value); }, log.fn('promise error'));
+ expect(log).toEqual([]);
+
+ $timeout.flush();
+ expect(log).toEqual(['promise success: undefined']);
+
+ log.reset();
+ $timeout(1000).then(function(value) { log('promise success: ' + value); }, log.fn('promise error'));
+ expect(log).toEqual([]);
+
+ $timeout.flush(500);
+ expect(log).toEqual([]);
+ $timeout.flush(500);
+ expect(log).toEqual(['promise success: undefined']);
+ }));
+
+
describe('exception handling', function() {
beforeEach(module(function($exceptionHandlerProvider) {
@@ -165,19 +184,24 @@ describe('$timeout', function() {
var task1 = jasmine.createSpy('task1'),
task2 = jasmine.createSpy('task2'),
task3 = jasmine.createSpy('task3'),
- promise1, promise3;
+ task4 = jasmine.createSpy('task4'),
+ promise1, promise3, promise4;
promise1 = $timeout(task1);
$timeout(task2);
promise3 = $timeout(task3, 333);
+ promise4 = $timeout(333);
+ promise3.then(task4);
- $timeout.cancel(promise3);
$timeout.cancel(promise1);
+ $timeout.cancel(promise3);
+ $timeout.cancel(promise4);
$timeout.flush();
expect(task1).not.toHaveBeenCalled();
expect(task2).toHaveBeenCalledOnce();
expect(task3).not.toHaveBeenCalled();
+ expect(task4).not.toHaveBeenCalled();
}));

0 comments on commit 5a60302

Please sign in to comment.