forked from angular/angular.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtimeout.js
97 lines (84 loc) · 3.19 KB
/
timeout.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
'use strict';
function $TimeoutProvider() {
this.$get = ['$rootScope', '$browser', '$q', '$$q', '$exceptionHandler',
function($rootScope, $browser, $q, $$q, $exceptionHandler) {
var deferreds = {};
/**
* @ngdoc service
* @name $timeout
*
* @description
* Angular's wrapper for `window.setTimeout`. The `fn` function is wrapped into a try/catch
* block and delegates any exceptions to
* {@link ng.$exceptionHandler $exceptionHandler} service.
*
* 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.
*
* 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.
* @param {...*=} Pass additional parameters to the executed function.
* @returns {Promise} 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) {
if (!isFunction(fn)) {
invokeApply = delay;
delay = fn;
fn = noop;
}
var args = sliceArgs(arguments, 3),
skipApply = (isDefined(invokeApply) && !invokeApply),
deferred = (skipApply ? $$q : $q).defer(),
promise = deferred.promise,
timeoutId;
timeoutId = $browser.defer(function() {
try {
deferred.resolve(fn.apply(null, args));
} catch (e) {
deferred.reject(e);
$exceptionHandler(e);
}
finally {
delete deferreds[promise.$$timeoutId];
}
if (!skipApply) $rootScope.$apply();
}, delay);
promise.$$timeoutId = timeoutId;
deferreds[timeoutId] = deferred;
return promise;
}
/**
* @ngdoc method
* @name $timeout#cancel
*
* @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 && promise.$$timeoutId in deferreds) {
deferreds[promise.$$timeoutId].reject('canceled');
delete deferreds[promise.$$timeoutId];
return $browser.defer.cancel(promise.$$timeoutId);
}
return false;
};
return timeout;
}];
}