2 module.exports = function(Promise, INTERNAL, tryConvertToPromise,
3 apiRejection, Proxyable) {
4 var util = require("./util");
5 var isArray = util.isArray;
7 function toResolutionValue(val) {
14 function PromiseArray(values) {
15 var promise = this._promise = new Promise(INTERNAL);
16 if (values instanceof Promise) {
17 promise._propagateFrom(values, 3);
19 promise._setOnCancel(this);
20 this._values = values;
22 this._totalResolved = 0;
23 this._init(undefined, -2);
25 util.inherits(PromiseArray, Proxyable);
27 PromiseArray.prototype.length = function () {
31 PromiseArray.prototype.promise = function () {
35 PromiseArray.prototype._init = function init(_, resolveValueIfEmpty) {
36 var values = tryConvertToPromise(this._values, this._promise);
37 if (values instanceof Promise) {
38 values = values._target();
39 var bitField = values._bitField;
41 this._values = values;
43 if (((bitField & 50397184) === 0)) {
44 this._promise._setAsyncGuaranteed();
52 } else if (((bitField & 33554432) !== 0)) {
53 values = values._value();
54 } else if (((bitField & 16777216) !== 0)) {
55 return this._reject(values._reason());
57 return this._cancel();
60 values = util.asArray(values);
61 if (values === null) {
62 var err = apiRejection(
63 "expecting an array or an iterable object but got " + util.classString(values)).reason();
64 this._promise._rejectCallback(err, false);
68 if (values.length === 0) {
69 if (resolveValueIfEmpty === -5) {
70 this._resolveEmptyArray();
73 this._resolve(toResolutionValue(resolveValueIfEmpty));
77 this._iterate(values);
80 PromiseArray.prototype._iterate = function(values) {
81 var len = this.getActualLength(values.length);
83 this._values = this.shouldCopyValues() ? new Array(len) : this._values;
84 var result = this._promise;
85 var isResolved = false;
87 for (var i = 0; i < len; ++i) {
88 var maybePromise = tryConvertToPromise(values[i], result);
90 if (maybePromise instanceof Promise) {
91 maybePromise = maybePromise._target();
92 bitField = maybePromise._bitField;
98 if (bitField !== null) {
99 maybePromise.suppressUnhandledRejections();
101 } else if (bitField !== null) {
102 if (((bitField & 50397184) === 0)) {
103 maybePromise._proxy(this, i);
104 this._values[i] = maybePromise;
105 } else if (((bitField & 33554432) !== 0)) {
106 isResolved = this._promiseFulfilled(maybePromise._value(), i);
107 } else if (((bitField & 16777216) !== 0)) {
108 isResolved = this._promiseRejected(maybePromise._reason(), i);
110 isResolved = this._promiseCancelled(i);
113 isResolved = this._promiseFulfilled(maybePromise, i);
116 if (!isResolved) result._setAsyncGuaranteed();
119 PromiseArray.prototype._isResolved = function () {
120 return this._values === null;
123 PromiseArray.prototype._resolve = function (value) {
125 this._promise._fulfill(value);
128 PromiseArray.prototype._cancel = function() {
129 if (this._isResolved() || !this._promise.isCancellable()) return;
131 this._promise._cancel();
134 PromiseArray.prototype._reject = function (reason) {
136 this._promise._rejectCallback(reason, false);
139 PromiseArray.prototype._promiseFulfilled = function (value, index) {
140 this._values[index] = value;
141 var totalResolved = ++this._totalResolved;
142 if (totalResolved >= this._length) {
143 this._resolve(this._values);
149 PromiseArray.prototype._promiseCancelled = function() {
154 PromiseArray.prototype._promiseRejected = function (reason) {
155 this._totalResolved++;
156 this._reject(reason);
160 PromiseArray.prototype._resultCancelled = function() {
161 if (this._isResolved()) return;
162 var values = this._values;
164 if (values instanceof Promise) {
167 for (var i = 0; i < values.length; ++i) {
168 if (values[i] instanceof Promise) {
175 PromiseArray.prototype.shouldCopyValues = function () {
179 PromiseArray.prototype.getActualLength = function (len) {