ca8b05e2b43a057e4ef88ec7bade185d3dfde339
[yaffs-website] / node_modules / es6-promise / lib / es6-promise / enumerator.js
1 import {
2   isArray,
3   isMaybeThenable
4 } from './utils';
5
6 import {
7   noop,
8   reject,
9   fulfill,
10   subscribe,
11   FULFILLED,
12   REJECTED,
13   PENDING,
14   getThen,
15   handleMaybeThenable
16 } from './-internal';
17
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';
23
24 export default Enumerator;
25 function Enumerator(Constructor, input) {
26   this._instanceConstructor = Constructor;
27   this.promise = new Constructor(noop);
28
29   if (!this.promise[PROMISE_ID]) {
30     makePromise(this.promise);
31   }
32
33   if (isArray(input)) {
34     this._input     = input;
35     this.length     = input.length;
36     this._remaining = input.length;
37
38     this._result = new Array(this.length);
39
40     if (this.length === 0) {
41       fulfill(this.promise, this._result);
42     } else {
43       this.length = this.length || 0;
44       this._enumerate();
45       if (this._remaining === 0) {
46         fulfill(this.promise, this._result);
47       }
48     }
49   } else {
50     reject(this.promise, validationError());
51   }
52 }
53
54 function validationError() {
55   return new Error('Array Methods must be provided an Array');
56 };
57
58 Enumerator.prototype._enumerate = function() {
59   let { length, _input } = this;
60
61   for (let i = 0; this._state === PENDING && i < length; i++) {
62     this._eachEntry(_input[i], i);
63   }
64 };
65
66 Enumerator.prototype._eachEntry = function(entry, i) {
67   let c = this._instanceConstructor;
68   let { resolve } = c;
69
70   if (resolve === originalResolve) {
71     let then = getThen(entry);
72
73     if (then === originalThen &&
74         entry._state !== PENDING) {
75       this._settledAt(entry._state, i, entry._result);
76     } else if (typeof then !== 'function') {
77       this._remaining--;
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);
83     } else {
84       this._willSettleAt(new c(resolve => resolve(entry)), i);
85     }
86   } else {
87     this._willSettleAt(resolve(entry), i);
88   }
89 };
90
91 Enumerator.prototype._settledAt = function(state, i, value) {
92   let { promise } = this;
93
94   if (promise._state === PENDING) {
95     this._remaining--;
96
97     if (state === REJECTED) {
98       reject(promise, value);
99     } else {
100       this._result[i] = value;
101     }
102   }
103
104   if (this._remaining === 0) {
105     fulfill(promise, this._result);
106   }
107 };
108
109 Enumerator.prototype._willSettleAt = function(promise, i) {
110   let enumerator = this;
111
112   subscribe(promise, undefined, value => enumerator._settledAt(FULFILLED, i, value),
113                                reason => enumerator._settledAt(REJECTED, i, reason));
114 };