b2e8f1cc580c2204bec8bc46218157a683a383d0
[aai/esr-gui.git] /
1 "use strict";
2 module.exports = function(Promise, INTERNAL, tryConvertToPromise,
3     apiRejection) {
4 var util = require("./util.js");
5 var isArray = util.isArray;
6
7 function toResolutionValue(val) {
8     switch(val) {
9     case -2: return [];
10     case -3: return {};
11     }
12 }
13
14 function PromiseArray(values) {
15     var promise = this._promise = new Promise(INTERNAL);
16     var parent;
17     if (values instanceof Promise) {
18         parent = values;
19         promise._propagateFrom(parent, 1 | 4);
20     }
21     this._values = values;
22     this._length = 0;
23     this._totalResolved = 0;
24     this._init(undefined, -2);
25 }
26 PromiseArray.prototype.length = function () {
27     return this._length;
28 };
29
30 PromiseArray.prototype.promise = function () {
31     return this._promise;
32 };
33
34 PromiseArray.prototype._init = function init(_, resolveValueIfEmpty) {
35     var values = tryConvertToPromise(this._values, this._promise);
36     if (values instanceof Promise) {
37         values = values._target();
38         this._values = values;
39         if (values._isFulfilled()) {
40             values = values._value();
41             if (!isArray(values)) {
42                 var err = new Promise.TypeError("expecting an array, a promise or a thenable\u000a\u000a    See http://goo.gl/s8MMhc\u000a");
43                 this.__hardReject__(err);
44                 return;
45             }
46         } else if (values._isPending()) {
47             values._then(
48                 init,
49                 this._reject,
50                 undefined,
51                 this,
52                 resolveValueIfEmpty
53            );
54             return;
55         } else {
56             this._reject(values._reason());
57             return;
58         }
59     } else if (!isArray(values)) {
60         this._promise._reject(apiRejection("expecting an array, a promise or a thenable\u000a\u000a    See http://goo.gl/s8MMhc\u000a")._reason());
61         return;
62     }
63
64     if (values.length === 0) {
65         if (resolveValueIfEmpty === -5) {
66             this._resolveEmptyArray();
67         }
68         else {
69             this._resolve(toResolutionValue(resolveValueIfEmpty));
70         }
71         return;
72     }
73     var len = this.getActualLength(values.length);
74     this._length = len;
75     this._values = this.shouldCopyValues() ? new Array(len) : this._values;
76     var promise = this._promise;
77     for (var i = 0; i < len; ++i) {
78         var isResolved = this._isResolved();
79         var maybePromise = tryConvertToPromise(values[i], promise);
80         if (maybePromise instanceof Promise) {
81             maybePromise = maybePromise._target();
82             if (isResolved) {
83                 maybePromise._ignoreRejections();
84             } else if (maybePromise._isPending()) {
85                 maybePromise._proxyPromiseArray(this, i);
86             } else if (maybePromise._isFulfilled()) {
87                 this._promiseFulfilled(maybePromise._value(), i);
88             } else {
89                 this._promiseRejected(maybePromise._reason(), i);
90             }
91         } else if (!isResolved) {
92             this._promiseFulfilled(maybePromise, i);
93         }
94     }
95 };
96
97 PromiseArray.prototype._isResolved = function () {
98     return this._values === null;
99 };
100
101 PromiseArray.prototype._resolve = function (value) {
102     this._values = null;
103     this._promise._fulfill(value);
104 };
105
106 PromiseArray.prototype.__hardReject__ =
107 PromiseArray.prototype._reject = function (reason) {
108     this._values = null;
109     this._promise._rejectCallback(reason, false, true);
110 };
111
112 PromiseArray.prototype._promiseProgressed = function (progressValue, index) {
113     this._promise._progress({
114         index: index,
115         value: progressValue
116     });
117 };
118
119
120 PromiseArray.prototype._promiseFulfilled = function (value, index) {
121     this._values[index] = value;
122     var totalResolved = ++this._totalResolved;
123     if (totalResolved >= this._length) {
124         this._resolve(this._values);
125     }
126 };
127
128 PromiseArray.prototype._promiseRejected = function (reason, index) {
129     this._totalResolved++;
130     this._reject(reason);
131 };
132
133 PromiseArray.prototype.shouldCopyValues = function () {
134     return true;
135 };
136
137 PromiseArray.prototype.getActualLength = function (len) {
138     return len;
139 };
140
141 return PromiseArray;
142 };