18 import then from './then';
19 import Promise from './promise';
20 import originalResolve from './promise/resolve';
21 import originalThen from './then';
22 import { makePromise, PROMISE_ID } from './-internal';
24 export default Enumerator;
25 function Enumerator(Constructor, input) {
26 this._instanceConstructor = Constructor;
27 this.promise = new Constructor(noop);
29 if (!this.promise[PROMISE_ID]) {
30 makePromise(this.promise);
35 this.length = input.length;
36 this._remaining = input.length;
38 this._result = new Array(this.length);
40 if (this.length === 0) {
41 fulfill(this.promise, this._result);
43 this.length = this.length || 0;
45 if (this._remaining === 0) {
46 fulfill(this.promise, this._result);
50 reject(this.promise, validationError());
54 function validationError() {
55 return new Error('Array Methods must be provided an Array');
58 Enumerator.prototype._enumerate = function() {
59 let { length, _input } = this;
61 for (let i = 0; this._state === PENDING && i < length; i++) {
62 this._eachEntry(_input[i], i);
66 Enumerator.prototype._eachEntry = function(entry, i) {
67 let c = this._instanceConstructor;
70 if (resolve === originalResolve) {
71 let then = getThen(entry);
73 if (then === originalThen &&
74 entry._state !== PENDING) {
75 this._settledAt(entry._state, i, entry._result);
76 } else if (typeof then !== 'function') {
78 this._result[i] = entry;
79 } else if (c === Promise) {
80 let promise = new c(noop);
81 handleMaybeThenable(promise, entry, then);
82 this._willSettleAt(promise, i);
84 this._willSettleAt(new c(resolve => resolve(entry)), i);
87 this._willSettleAt(resolve(entry), i);
91 Enumerator.prototype._settledAt = function(state, i, value) {
92 let { promise } = this;
94 if (promise._state === PENDING) {
97 if (state === REJECTED) {
98 reject(promise, value);
100 this._result[i] = value;
104 if (this._remaining === 0) {
105 fulfill(promise, this._result);
109 Enumerator.prototype._willSettleAt = function(promise, i) {
110 let enumerator = this;
112 subscribe(promise, undefined, value => enumerator._settledAt(FULFILLED, i, value),
113 reason => enumerator._settledAt(REJECTED, i, reason));