-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjquery.whenall.js
98 lines (98 loc) · 2.97 KB
/
jquery.whenall.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
98
/**
* Created by galbi on 5/6/2016.
*/
(function(factory) {
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
define(["jquery"], factory);
}
else {
// Browser globals
factory(jQuery);
}
}(function($) {
$.whenAll = function() {
var masterDeferred = $.Deferred(),
deferreds = [],
progressDeferreds = [],
allFulfilled = false,
initialProgress = true,
notifyMasterDeferred = function() {
masterDeferred.notify.apply(
masterDeferred,
progressDeferreds.length > 1 ?
$.makeArray(progressDeferreds).map(function(progressDeferred) {
return progressDeferred.__latestArgs__.length > 1 ?
$.makeArray(progressDeferred.__latestArgs__)
: (progressDeferred.__latestArgs__.length == 1 ? progressDeferred.__latestArgs__[0] : void 0);
})
: arguments
);
},
hasRejected = false;
$.each(arguments, function(i, promise) {
var deferred = $.Deferred();
var progressDeferred = $.Deferred();
if (promise && promise.then) {
var afterFulfillment = function() {
deferred.resolve.apply(deferred, arguments);
if (initialProgress) {
progressDeferred.__latestArgs__ = arguments;
progressDeferred.resolve.apply(progressDeferred, arguments);
}
};
promise.then(
// done
afterFulfillment,
// fail
function() {
hasRejected = true;
afterFulfillment.apply(this, arguments);
},
// progress
function() {
// if progress received while there are still promises who aren't fulfilled/progressed
progressDeferred.__latestArgs__ = arguments;
if (initialProgress) {
progressDeferred.resolve.apply(progressDeferred, arguments);
}
// if all promises are either fulfilled or progressed
else {
notifyMasterDeferred.apply(null, arguments);
}
}
);
}
else {
deferred.resolve(promise);
progressDeferred.__latestArgs__ = [promise];
progressDeferred.resolve(promise);
}
deferreds.push(deferred);
progressDeferreds.push(progressDeferred);
});
/*
when all the promises are in final state (resolved/rejected) - if even
one of the promises is rejected, the returned master promise is rejected iff one or more of the promises are rejected.
otherwise, it's resolved.
*/
$.when.apply($, deferreds).done(function() {
allFulfilled = true;
masterDeferred[hasRejected ? 'reject' : 'resolve'].apply(masterDeferred, arguments);
});
/*
when at least one of the promises has "progressed", while
all the others are resolved/rejected - the returned master promise
is notifying a "progress".
For each further "progress" notification coming from the unsettled promises, a further notification will be
called on the master promise.
*/
$.when.apply($, progressDeferreds).done(function() {
if (!allFulfilled) {
notifyMasterDeferred.apply(null, arguments);
initialProgress = false;
}
});
return masterDeferred.promise();
};
}));