-
Notifications
You must be signed in to change notification settings - Fork 3
/
angular-q-limit.js
67 lines (60 loc) · 2.05 KB
/
angular-q-limit.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
angular.module('angular-q-limit', [])
.config(['$provide', function($provide) {
$provide.decorator('$q', ['$delegate', function($delegate) {
/**
* Execute $q.all() with limits
*
* @name $q.allLimit()
* @fires resolve Resolved will receive an array of all completed promise values
* @fires reject Reject will return with the first error of the first failed promise
* @fires progress Progress will be of the form `{completed: Number, count: Number, limit: Number}`
* @param {number} [limit=1] The maximum number of promises to run at once
* @return {Promise} The outer promise of the all() resolver
*/
$delegate.allLimit = function() {
var limit = 1; // Set the initial limit
// Prepare list of promises we should process - also extract any numbers from the list as the limit to use {{{
var promises = _(arguments)
.filter(function(arg) {
var isLimit = _.isNumber(arg);
if (isLimit) limit = arg;
return !isLimit;
})
.flatten()
.value();
// }}}
var defer = $delegate.defer();
var promiseChecker = function(queue) {
if (!queue.promisesRemaining.length && queue.running == 0) return queue.defer.resolve(_(queue.output).map().value());
while (queue.promisesRemaining.length > 0 && queue.running < queue.limit) {
var promiseRunner = function(thisPromise, promiseIndex) {
queue.running++;
$delegate.resolve(thisPromise())
.then(function(data) {
queue.output[promiseIndex] = data;
queue.completed++;
queue.running--;
queue.defer.notify({completed: queue.completed, count: queue.promiseCount, limit: queue.limit});
promiseChecker(queue);
})
.catch(function(err) {
queue.defer.reject(err);
});
}(queue.promisesRemaining.shift(), queue.promiseIndex++);
}
};
promiseChecker({
limit: limit,
running: 0,
promiseCount: promises.length,
completed: 0,
defer: defer,
promisesRemaining: promises,
output: [],
promiseIndex: 0,
});
return defer.promise;
};
return $delegate;
}]);
}]);