• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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