
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
import {
isArray,
isMaybeThenable
} from './utils';
import {
noop,
reject,
fulfill,
subscribe,
FULFILLED,
REJECTED,
PENDING,
handleMaybeThenable
} from './-internal';
import then from './then';
import Promise from './promise';
import originalResolve from './promise/resolve';
import originalThen from './then';
import { makePromise, PROMISE_ID } from './-internal';
function validationError() {
return new Error('Array Methods must be provided an Array');
};
export default class Enumerator {
constructor(Constructor, input) {
this._instanceConstructor = Constructor;
this.promise = new Constructor(noop);
if (!this.promise[PROMISE_ID]) {
makePromise(this.promise);
}
if (isArray(input)) {
this.length = input.length;
this._remaining = input.length;
this._result = new Array(this.length);
if (this.length === 0) {
fulfill(this.promise, this._result);
} else {
this.length = this.length || 0;
this._enumerate(input);
if (this._remaining === 0) {
fulfill(this.promise, this._result);
}
}
} else {
reject(this.promise, validationError());
}
}
_enumerate(input) {
for (let i = 0; this._state === PENDING && i < input.length; i++) {
this._eachEntry(input[i], i);
}
}
_eachEntry(entry, i) {
let c = this._instanceConstructor;
let { resolve } = c;
if (resolve === originalResolve) {
let then;
let error;
let didError = false;
try {
then = entry.then;
} catch (e) {
didError = true;
error = e;
}
if (then === originalThen &&
entry._state !== PENDING) {
this._settledAt(entry._state, i, entry._result);
} else if (typeof then !== 'function') {
this._remaining--;
this._result[i] = entry;
} else if (c === Promise) {
let promise = new c(noop);
if (didError) {
reject(promise, error);
} else {
handleMaybeThenable(promise, entry, then);
}
this._willSettleAt(promise, i);
} else {
this._willSettleAt(new c(resolve => resolve(entry)), i);
}
} else {
this._willSettleAt(resolve(entry), i);
}
}
_settledAt(state, i, value) {
let { promise } = this;
if (promise._state === PENDING) {
this._remaining--;
if (state === REJECTED) {
reject(promise, value);
} else {
this._result[i] = value;
}
}
if (this._remaining === 0) {
fulfill(promise, this._result);
}
}
_willSettleAt(promise, i) {
let enumerator = this;
subscribe(
promise, undefined,
value => enumerator._settledAt(FULFILLED, i, value),
reason => enumerator._settledAt(REJECTED, i, reason)
);
}
};