Security update for Core, with self-updated composer
[yaffs-website] / node_modules / es6-promise / lib / es6-promise / promise.js
1 import {
2   isFunction
3 } from './utils';
4
5 import {
6   noop,
7   nextId,
8   PROMISE_ID,
9   initializePromise
10 } from './-internal';
11
12 import {
13   asap,
14   setAsap,
15   setScheduler
16 } from './asap';
17
18 import all from './promise/all';
19 import race from './promise/race';
20 import Resolve from './promise/resolve';
21 import Reject from './promise/reject';
22 import then from './then';
23
24
25 function needsResolver() {
26   throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
27 }
28
29 function needsNew() {
30   throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
31 }
32
33 /**
34   Promise objects represent the eventual result of an asynchronous operation. The
35   primary way of interacting with a promise is through its `then` method, which
36   registers callbacks to receive either a promise's eventual value or the reason
37   why the promise cannot be fulfilled.
38
39   Terminology
40   -----------
41
42   - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
43   - `thenable` is an object or function that defines a `then` method.
44   - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
45   - `exception` is a value that is thrown using the throw statement.
46   - `reason` is a value that indicates why a promise was rejected.
47   - `settled` the final resting state of a promise, fulfilled or rejected.
48
49   A promise can be in one of three states: pending, fulfilled, or rejected.
50
51   Promises that are fulfilled have a fulfillment value and are in the fulfilled
52   state.  Promises that are rejected have a rejection reason and are in the
53   rejected state.  A fulfillment value is never a thenable.
54
55   Promises can also be said to *resolve* a value.  If this value is also a
56   promise, then the original promise's settled state will match the value's
57   settled state.  So a promise that *resolves* a promise that rejects will
58   itself reject, and a promise that *resolves* a promise that fulfills will
59   itself fulfill.
60
61
62   Basic Usage:
63   ------------
64
65   ```js
66   let promise = new Promise(function(resolve, reject) {
67     // on success
68     resolve(value);
69
70     // on failure
71     reject(reason);
72   });
73
74   promise.then(function(value) {
75     // on fulfillment
76   }, function(reason) {
77     // on rejection
78   });
79   ```
80
81   Advanced Usage:
82   ---------------
83
84   Promises shine when abstracting away asynchronous interactions such as
85   `XMLHttpRequest`s.
86
87   ```js
88   function getJSON(url) {
89     return new Promise(function(resolve, reject){
90       let xhr = new XMLHttpRequest();
91
92       xhr.open('GET', url);
93       xhr.onreadystatechange = handler;
94       xhr.responseType = 'json';
95       xhr.setRequestHeader('Accept', 'application/json');
96       xhr.send();
97
98       function handler() {
99         if (this.readyState === this.DONE) {
100           if (this.status === 200) {
101             resolve(this.response);
102           } else {
103             reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
104           }
105         }
106       };
107     });
108   }
109
110   getJSON('/posts.json').then(function(json) {
111     // on fulfillment
112   }, function(reason) {
113     // on rejection
114   });
115   ```
116
117   Unlike callbacks, promises are great composable primitives.
118
119   ```js
120   Promise.all([
121     getJSON('/posts'),
122     getJSON('/comments')
123   ]).then(function(values){
124     values[0] // => postsJSON
125     values[1] // => commentsJSON
126
127     return values;
128   });
129   ```
130
131   @class Promise
132   @param {function} resolver
133   Useful for tooling.
134   @constructor
135 */
136 export default function Promise(resolver) {
137   this[PROMISE_ID] = nextId();
138   this._result = this._state = undefined;
139   this._subscribers = [];
140
141   if (noop !== resolver) {
142     typeof resolver !== 'function' && needsResolver();
143     this instanceof Promise ? initializePromise(this, resolver) : needsNew();
144   }
145 }
146
147 Promise.all = all;
148 Promise.race = race;
149 Promise.resolve = Resolve;
150 Promise.reject = Reject;
151 Promise._setScheduler = setScheduler;
152 Promise._setAsap = setAsap;
153 Promise._asap = asap;
154
155 Promise.prototype = {
156   constructor: Promise,
157
158 /**
159   The primary way of interacting with a promise is through its `then` method,
160   which registers callbacks to receive either a promise's eventual value or the
161   reason why the promise cannot be fulfilled.
162
163   ```js
164   findUser().then(function(user){
165     // user is available
166   }, function(reason){
167     // user is unavailable, and you are given the reason why
168   });
169   ```
170
171   Chaining
172   --------
173
174   The return value of `then` is itself a promise.  This second, 'downstream'
175   promise is resolved with the return value of the first promise's fulfillment
176   or rejection handler, or rejected if the handler throws an exception.
177
178   ```js
179   findUser().then(function (user) {
180     return user.name;
181   }, function (reason) {
182     return 'default name';
183   }).then(function (userName) {
184     // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
185     // will be `'default name'`
186   });
187
188   findUser().then(function (user) {
189     throw new Error('Found user, but still unhappy');
190   }, function (reason) {
191     throw new Error('`findUser` rejected and we're unhappy');
192   }).then(function (value) {
193     // never reached
194   }, function (reason) {
195     // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
196     // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
197   });
198   ```
199   If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
200
201   ```js
202   findUser().then(function (user) {
203     throw new PedagogicalException('Upstream error');
204   }).then(function (value) {
205     // never reached
206   }).then(function (value) {
207     // never reached
208   }, function (reason) {
209     // The `PedgagocialException` is propagated all the way down to here
210   });
211   ```
212
213   Assimilation
214   ------------
215
216   Sometimes the value you want to propagate to a downstream promise can only be
217   retrieved asynchronously. This can be achieved by returning a promise in the
218   fulfillment or rejection handler. The downstream promise will then be pending
219   until the returned promise is settled. This is called *assimilation*.
220
221   ```js
222   findUser().then(function (user) {
223     return findCommentsByAuthor(user);
224   }).then(function (comments) {
225     // The user's comments are now available
226   });
227   ```
228
229   If the assimliated promise rejects, then the downstream promise will also reject.
230
231   ```js
232   findUser().then(function (user) {
233     return findCommentsByAuthor(user);
234   }).then(function (comments) {
235     // If `findCommentsByAuthor` fulfills, we'll have the value here
236   }, function (reason) {
237     // If `findCommentsByAuthor` rejects, we'll have the reason here
238   });
239   ```
240
241   Simple Example
242   --------------
243
244   Synchronous Example
245
246   ```javascript
247   let result;
248
249   try {
250     result = findResult();
251     // success
252   } catch(reason) {
253     // failure
254   }
255   ```
256
257   Errback Example
258
259   ```js
260   findResult(function(result, err){
261     if (err) {
262       // failure
263     } else {
264       // success
265     }
266   });
267   ```
268
269   Promise Example;
270
271   ```javascript
272   findResult().then(function(result){
273     // success
274   }, function(reason){
275     // failure
276   });
277   ```
278
279   Advanced Example
280   --------------
281
282   Synchronous Example
283
284   ```javascript
285   let author, books;
286
287   try {
288     author = findAuthor();
289     books  = findBooksByAuthor(author);
290     // success
291   } catch(reason) {
292     // failure
293   }
294   ```
295
296   Errback Example
297
298   ```js
299
300   function foundBooks(books) {
301
302   }
303
304   function failure(reason) {
305
306   }
307
308   findAuthor(function(author, err){
309     if (err) {
310       failure(err);
311       // failure
312     } else {
313       try {
314         findBoooksByAuthor(author, function(books, err) {
315           if (err) {
316             failure(err);
317           } else {
318             try {
319               foundBooks(books);
320             } catch(reason) {
321               failure(reason);
322             }
323           }
324         });
325       } catch(error) {
326         failure(err);
327       }
328       // success
329     }
330   });
331   ```
332
333   Promise Example;
334
335   ```javascript
336   findAuthor().
337     then(findBooksByAuthor).
338     then(function(books){
339       // found books
340   }).catch(function(reason){
341     // something went wrong
342   });
343   ```
344
345   @method then
346   @param {Function} onFulfilled
347   @param {Function} onRejected
348   Useful for tooling.
349   @return {Promise}
350 */
351   then: then,
352
353 /**
354   `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
355   as the catch block of a try/catch statement.
356
357   ```js
358   function findAuthor(){
359     throw new Error('couldn't find that author');
360   }
361
362   // synchronous
363   try {
364     findAuthor();
365   } catch(reason) {
366     // something went wrong
367   }
368
369   // async with promises
370   findAuthor().catch(function(reason){
371     // something went wrong
372   });
373   ```
374
375   @method catch
376   @param {Function} onRejection
377   Useful for tooling.
378   @return {Promise}
379 */
380   catch(onRejection) {
381     return this.then(null, onRejection);
382   }
383 };