1"use strict"; 2module.exports = function(Promise, INTERNAL, tryConvertToPromise, 3 apiRejection, Proxyable) { 4var util = require("./util"); 5var isArray = util.isArray; 6 7function toResolutionValue(val) { 8 switch(val) { 9 case -2: return []; 10 case -3: return {}; 11 case -6: return new Map(); 12 } 13} 14 15function PromiseArray(values) { 16 var promise = this._promise = new Promise(INTERNAL); 17 if (values instanceof Promise) { 18 promise._propagateFrom(values, 3); 19 } 20 promise._setOnCancel(this); 21 this._values = values; 22 this._length = 0; 23 this._totalResolved = 0; 24 this._init(undefined, -2); 25} 26util.inherits(PromiseArray, Proxyable); 27 28PromiseArray.prototype.length = function () { 29 return this._length; 30}; 31 32PromiseArray.prototype.promise = function () { 33 return this._promise; 34}; 35 36PromiseArray.prototype._init = function init(_, resolveValueIfEmpty) { 37 var values = tryConvertToPromise(this._values, this._promise); 38 if (values instanceof Promise) { 39 values = values._target(); 40 var bitField = values._bitField; 41 ; 42 this._values = values; 43 44 if (((bitField & 50397184) === 0)) { 45 this._promise._setAsyncGuaranteed(); 46 return values._then( 47 init, 48 this._reject, 49 undefined, 50 this, 51 resolveValueIfEmpty 52 ); 53 } else if (((bitField & 33554432) !== 0)) { 54 values = values._value(); 55 } else if (((bitField & 16777216) !== 0)) { 56 return this._reject(values._reason()); 57 } else { 58 return this._cancel(); 59 } 60 } 61 values = util.asArray(values); 62 if (values === null) { 63 var err = apiRejection( 64 "expecting an array or an iterable object but got " + util.classString(values)).reason(); 65 this._promise._rejectCallback(err, false); 66 return; 67 } 68 69 if (values.length === 0) { 70 if (resolveValueIfEmpty === -5) { 71 this._resolveEmptyArray(); 72 } 73 else { 74 this._resolve(toResolutionValue(resolveValueIfEmpty)); 75 } 76 return; 77 } 78 this._iterate(values); 79}; 80 81PromiseArray.prototype._iterate = function(values) { 82 var len = this.getActualLength(values.length); 83 this._length = len; 84 this._values = this.shouldCopyValues() ? new Array(len) : this._values; 85 var result = this._promise; 86 var isResolved = false; 87 var bitField = null; 88 for (var i = 0; i < len; ++i) { 89 var maybePromise = tryConvertToPromise(values[i], result); 90 91 if (maybePromise instanceof Promise) { 92 maybePromise = maybePromise._target(); 93 bitField = maybePromise._bitField; 94 } else { 95 bitField = null; 96 } 97 98 if (isResolved) { 99 if (bitField !== null) { 100 maybePromise.suppressUnhandledRejections(); 101 } 102 } else if (bitField !== null) { 103 if (((bitField & 50397184) === 0)) { 104 maybePromise._proxy(this, i); 105 this._values[i] = maybePromise; 106 } else if (((bitField & 33554432) !== 0)) { 107 isResolved = this._promiseFulfilled(maybePromise._value(), i); 108 } else if (((bitField & 16777216) !== 0)) { 109 isResolved = this._promiseRejected(maybePromise._reason(), i); 110 } else { 111 isResolved = this._promiseCancelled(i); 112 } 113 } else { 114 isResolved = this._promiseFulfilled(maybePromise, i); 115 } 116 } 117 if (!isResolved) result._setAsyncGuaranteed(); 118}; 119 120PromiseArray.prototype._isResolved = function () { 121 return this._values === null; 122}; 123 124PromiseArray.prototype._resolve = function (value) { 125 this._values = null; 126 this._promise._fulfill(value); 127}; 128 129PromiseArray.prototype._cancel = function() { 130 if (this._isResolved() || !this._promise._isCancellable()) return; 131 this._values = null; 132 this._promise._cancel(); 133}; 134 135PromiseArray.prototype._reject = function (reason) { 136 this._values = null; 137 this._promise._rejectCallback(reason, false); 138}; 139 140PromiseArray.prototype._promiseFulfilled = function (value, index) { 141 this._values[index] = value; 142 var totalResolved = ++this._totalResolved; 143 if (totalResolved >= this._length) { 144 this._resolve(this._values); 145 return true; 146 } 147 return false; 148}; 149 150PromiseArray.prototype._promiseCancelled = function() { 151 this._cancel(); 152 return true; 153}; 154 155PromiseArray.prototype._promiseRejected = function (reason) { 156 this._totalResolved++; 157 this._reject(reason); 158 return true; 159}; 160 161PromiseArray.prototype._resultCancelled = function() { 162 if (this._isResolved()) return; 163 var values = this._values; 164 this._cancel(); 165 if (values instanceof Promise) { 166 values.cancel(); 167 } else { 168 for (var i = 0; i < values.length; ++i) { 169 if (values[i] instanceof Promise) { 170 values[i].cancel(); 171 } 172 } 173 } 174}; 175 176PromiseArray.prototype.shouldCopyValues = function () { 177 return true; 178}; 179 180PromiseArray.prototype.getActualLength = function (len) { 181 return len; 182}; 183 184return PromiseArray; 185}; 186