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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177 |
8
8
8
8
8
31
28
3
8
1765
1765
1765
1765
346
346
1765
1765
1765
1765
8
13975
8
1765
8
1825
1825
426
426
426
426
339
339
91
91
91
87
71
71
71
71
16
16
1399
21
21
1626
106
75
31
106
1520
1520
1520
1520
1520
10308
10308
10308
2708
2708
84
2624
2195
429
299
130
7600
7498
8
34032
8
1462
1462
1462
1462
8
279
279
279
8
45
45
45
8
508
508
508
508
508
508
168
8
96
96
96
96
96
8
1472
8
1472
8
| (function () { "use strict";
module.exports = function(Promise, INTERNAL, tryConvertToPromise,
apiRejection) {
var ASSERT = require("./assert.js");
var util = require("./util.js");
var isArray = util.isArray;
function toResolutionValue(val) {
switch(val) {
case -2: return [];
case -3: return {};
}
ASSERT(false,
"false");
}
function PromiseArray(values) {
ASSERT((arguments.length === 1),
"arguments.length === 1");
var promise = this._promise = new Promise(INTERNAL);
var parent;
if (values instanceof Promise) {
parent = values;
promise._propagateFrom(parent, 1 | 4);
}
this._values = values;
this._length = 0;
this._totalResolved = 0;
this._init(undefined, -2);
}
PromiseArray.prototype.length = function () {
return this._length;
};
PromiseArray.prototype.promise = function () {
return this._promise;
};
PromiseArray.prototype._init = function init(_, resolveValueIfEmpty) {
var values = tryConvertToPromise(this._values, this._promise);
if (values instanceof Promise) {
values._setBoundTo(this._promise._boundTo);
values = values._target();
this._values = values;
if (values._isFulfilled()) {
values = values._value();
if (!isArray(values)) {
var err = new Promise.TypeError("expecting an array, a promise or a thenable\u000a\u000a See http://goo.gl/s8MMhc\u000a");
this.__hardReject__(err);
return;
}
} else if (values._isPending()) {
ASSERT(((typeof resolveValueIfEmpty) === "number"),
"typeof resolveValueIfEmpty === \u0022number\u0022");
ASSERT((resolveValueIfEmpty < 0),
"resolveValueIfEmpty < 0");
values._then(
init,
this._reject,
undefined,
this,
resolveValueIfEmpty
);
return;
} else {
this._reject(values._reason());
return;
}
} else if (!isArray(values)) {
this._promise._follow(apiRejection("expecting an array, a promise or a thenable\u000a\u000a See http://goo.gl/s8MMhc\u000a"));
return;
}
if (values.length === 0) {
if (resolveValueIfEmpty === -5) {
this._resolveEmptyArray();
}
else {
this._resolve(toResolutionValue(resolveValueIfEmpty));
}
return;
}
var len = this.getActualLength(values.length);
this._length = len;
this._values = this.shouldCopyValues() ? new Array(len) : this._values;
var promise = this._promise;
for (var i = 0; i < len; ++i) {
var isResolved = this._isResolved();
var maybePromise = tryConvertToPromise(values[i], promise);
if (maybePromise instanceof Promise) {
maybePromise = maybePromise._target();
if (isResolved) {
maybePromise._unsetRejectionIsUnhandled();
} else if (maybePromise._isPending()) {
maybePromise._proxyPromiseArray(this, i);
} else if (maybePromise._isFulfilled()) {
this._promiseFulfilled(maybePromise._value(), i);
} else {
this._promiseRejected(maybePromise._reason(), i);
}
} else if (!isResolved) {
this._promiseFulfilled(maybePromise, i);
}
}
};
PromiseArray.prototype._isResolved = function () {
return this._values === null;
};
PromiseArray.prototype._resolve = function (value) {
ASSERT((! this._isResolved()),
"!this._isResolved()");
ASSERT((! (value instanceof Promise)),
"!(value instanceof Promise)");
this._values = null;
this._promise._fulfill(value);
};
PromiseArray.prototype.__hardReject__ =
PromiseArray.prototype._reject = function (reason) {
ASSERT((! this._isResolved()),
"!this._isResolved()");
this._values = null;
this._promise._rejectCallback(reason, false, true);
};
PromiseArray.prototype._promiseProgressed = function (progressValue, index) {
ASSERT((! this._isResolved()),
"!this._isResolved()");
ASSERT(isArray(this._values),
"isArray(this._values)");
this._promise._progress({
index: index,
value: progressValue
});
};
PromiseArray.prototype._promiseFulfilled = function (value, index) {
ASSERT((! this._isResolved()),
"!this._isResolved()");
ASSERT(isArray(this._values),
"isArray(this._values)");
ASSERT(((typeof index) === "number"),
"typeof index === \u0022number\u0022");
this._values[index] = value;
var totalResolved = ++this._totalResolved;
if (totalResolved >= this._length) {
this._resolve(this._values);
}
};
PromiseArray.prototype._promiseRejected = function (reason, index) {
ASSERT((index >= 0),
"index >= 0");
ASSERT((! this._isResolved()),
"!this._isResolved()");
ASSERT(isArray(this._values),
"isArray(this._values)");
this._totalResolved++;
this._reject(reason);
};
PromiseArray.prototype.shouldCopyValues = function () {
return true;
};
PromiseArray.prototype.getActualLength = function (len) {
return len;
};
return PromiseArray;
};
}());
|