16 import then from './then';
17 import Promise from './promise';
18 import originalResolve from './promise/resolve';
19 import originalThen from './then';
20 import { makePromise, PROMISE_ID } from './-internal';
22 function validationError() {
23 return new Error('Array Methods must be provided an Array');
26 export default class Enumerator {
27 constructor(Constructor, input) {
28 this._instanceConstructor = Constructor;
29 this.promise = new Constructor(noop);
31 if (!this.promise[PROMISE_ID]) {
32 makePromise(this.promise);
36 this.length = input.length;
37 this._remaining = input.length;
39 this._result = new Array(this.length);
41 if (this.length === 0) {
42 fulfill(this.promise, this._result);
44 this.length = this.length || 0;
45 this._enumerate(input);
46 if (this._remaining === 0) {
47 fulfill(this.promise, this._result);
51 reject(this.promise, validationError());
55 for (let i = 0; this._state === PENDING && i < input.length; i++) {
56 this._eachEntry(input[i], i);
60 _eachEntry(entry, i) {
61 let c = this._instanceConstructor;
64 if (resolve === originalResolve) {
75 if (then === originalThen &&
76 entry._state !== PENDING) {
77 this._settledAt(entry._state, i, entry._result);
78 } else if (typeof then !== 'function') {
80 this._result[i] = entry;
81 } else if (c === Promise) {
82 let promise = new c(noop);
84 reject(promise, error);
86 handleMaybeThenable(promise, entry, then);
88 this._willSettleAt(promise, i);
90 this._willSettleAt(new c(resolve => resolve(entry)), i);
93 this._willSettleAt(resolve(entry), i);
97 _settledAt(state, i, value) {
98 let { promise } = this;
100 if (promise._state === PENDING) {
103 if (state === REJECTED) {
104 reject(promise, value);
106 this._result[i] = value;
110 if (this._remaining === 0) {
111 fulfill(promise, this._result);
115 _willSettleAt(promise, i) {
116 let enumerator = this;
120 value => enumerator._settledAt(FULFILLED, i, value),
121 reason => enumerator._settledAt(REJECTED, i, reason)