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 var length = this.length;
60 var input = this._input;
62 for (var i = 0; this._state === PENDING && i < length; i++) {
63 this._eachEntry(input[i], i);
67 Enumerator.prototype._eachEntry = function(entry, i) {
68 var c = this._instanceConstructor;
69 var resolve = c.resolve;
71 if (resolve === originalResolve) {
72 var then = getThen(entry);
74 if (then === originalThen &&
75 entry._state !== PENDING) {
76 this._settledAt(entry._state, i, entry._result);
77 } else if (typeof then !== 'function') {
79 this._result[i] = entry;
80 } else if (c === Promise) {
81 var promise = new c(noop);
82 handleMaybeThenable(promise, entry, then);
83 this._willSettleAt(promise, i);
85 this._willSettleAt(new c(function(resolve) { resolve(entry); }), i);
88 this._willSettleAt(resolve(entry), i);
92 Enumerator.prototype._settledAt = function(state, i, value) {
93 var promise = this.promise;
95 if (promise._state === PENDING) {
98 if (state === REJECTED) {
99 reject(promise, value);
101 this._result[i] = value;
105 if (this._remaining === 0) {
106 fulfill(promise, this._result);
110 Enumerator.prototype._willSettleAt = function(promise, i) {
111 var enumerator = this;
113 subscribe(promise, undefined, function(value) {
114 enumerator._settledAt(FULFILLED, i, value);
115 }, function(reason) {
116 enumerator._settledAt(REJECTED, i, reason);