| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- 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)
- );
- }
- };
|