2 * @overview es6-promise - a tiny implementation of Promises/A+.
3 * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
4 * @license Licensed under MIT license
5 * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE
6 * @version v4.2.8+1e68dce6
9 (function (global, factory) {
10 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
11 typeof define === 'function' && define.amd ? define(factory) :
12 (global.ES6Promise = factory());
13 }(this, (function () { 'use strict';
15 function objectOrFunction(x) {
17 return x !== null && (type === 'object' || type === 'function');
20 function isFunction(x) {
21 return typeof x === 'function';
26 var _isArray = void 0;
28 _isArray = Array.isArray;
30 _isArray = function (x) {
31 return Object.prototype.toString.call(x) === '[object Array]';
35 var isArray = _isArray;
38 var vertxNext = void 0;
39 var customSchedulerFn = void 0;
41 var asap = function asap(callback, arg) {
42 queue[len] = callback;
46 // If len is 2, that means that we need to schedule an async flush.
47 // If additional callbacks are queued before the queue is flushed, they
48 // will be processed by this flush that we are scheduling.
49 if (customSchedulerFn) {
50 customSchedulerFn(flush);
57 function setScheduler(scheduleFn) {
58 customSchedulerFn = scheduleFn;
61 function setAsap(asapFn) {
65 var browserWindow = typeof window !== 'undefined' ? window : undefined;
66 var browserGlobal = browserWindow || {};
67 var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
68 var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
70 // test for web worker but not in IE10
71 var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
74 function useNextTick() {
75 // node version 0.10.x displays a deprecation warning when nextTick is used recursively
76 // see https://github.com/cujojs/when/issues/410 for details
78 return process.nextTick(flush);
83 function useVertxTimer() {
84 if (typeof vertxNext !== 'undefined') {
90 return useSetTimeout();
93 function useMutationObserver() {
95 var observer = new BrowserMutationObserver(flush);
96 var node = document.createTextNode('');
97 observer.observe(node, { characterData: true });
100 node.data = iterations = ++iterations % 2;
105 function useMessageChannel() {
106 var channel = new MessageChannel();
107 channel.port1.onmessage = flush;
109 return channel.port2.postMessage(0);
113 function useSetTimeout() {
114 // Store setTimeout reference so es6-promise will be unaffected by
115 // other code modifying setTimeout (like sinon.useFakeTimers())
116 var globalSetTimeout = setTimeout;
118 return globalSetTimeout(flush, 1);
122 var queue = new Array(1000);
124 for (var i = 0; i < len; i += 2) {
125 var callback = queue[i];
126 var arg = queue[i + 1];
130 queue[i] = undefined;
131 queue[i + 1] = undefined;
137 function attemptVertx() {
139 var vertx = Function('return this')().require('vertx');
140 vertxNext = vertx.runOnLoop || vertx.runOnContext;
141 return useVertxTimer();
143 return useSetTimeout();
147 var scheduleFlush = void 0;
148 // Decide what async method to use to triggering processing of queued callbacks:
150 scheduleFlush = useNextTick();
151 } else if (BrowserMutationObserver) {
152 scheduleFlush = useMutationObserver();
153 } else if (isWorker) {
154 scheduleFlush = useMessageChannel();
155 } else if (browserWindow === undefined && typeof require === 'function') {
156 scheduleFlush = attemptVertx();
158 scheduleFlush = useSetTimeout();
161 function then(onFulfillment, onRejection) {
164 var child = new this.constructor(noop);
166 if (child[PROMISE_ID] === undefined) {
170 var _state = parent._state;
174 var callback = arguments[_state - 1];
176 return invokeCallback(_state, child, callback, parent._result);
179 subscribe(parent, child, onFulfillment, onRejection);
186 `Promise.resolve` returns a promise that will become resolved with the
187 passed `value`. It is shorthand for the following:
190 let promise = new Promise(function(resolve, reject){
194 promise.then(function(value){
199 Instead of writing the above, your code now simply becomes the following:
202 let promise = Promise.resolve(1);
204 promise.then(function(value){
211 @param {Any} value value that the returned promise will be resolved with
213 @return {Promise} a promise that will become fulfilled with the given
216 function resolve$1(object) {
217 /*jshint validthis:true */
218 var Constructor = this;
220 if (object && typeof object === 'object' && object.constructor === Constructor) {
224 var promise = new Constructor(noop);
225 resolve(promise, object);
229 var PROMISE_ID = Math.random().toString(36).substring(2);
233 var PENDING = void 0;
237 function selfFulfillment() {
238 return new TypeError("You cannot resolve a promise with itself");
241 function cannotReturnOwn() {
242 return new TypeError('A promises callback cannot return that same promise.');
245 function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) {
247 then$$1.call(value, fulfillmentHandler, rejectionHandler);
253 function handleForeignThenable(promise, thenable, then$$1) {
254 asap(function (promise) {
256 var error = tryThen(then$$1, thenable, function (value) {
261 if (thenable !== value) {
262 resolve(promise, value);
264 fulfill(promise, value);
266 }, function (reason) {
272 reject(promise, reason);
273 }, 'Settle: ' + (promise._label || ' unknown promise'));
275 if (!sealed && error) {
277 reject(promise, error);
282 function handleOwnThenable(promise, thenable) {
283 if (thenable._state === FULFILLED) {
284 fulfill(promise, thenable._result);
285 } else if (thenable._state === REJECTED) {
286 reject(promise, thenable._result);
288 subscribe(thenable, undefined, function (value) {
289 return resolve(promise, value);
290 }, function (reason) {
291 return reject(promise, reason);
296 function handleMaybeThenable(promise, maybeThenable, then$$1) {
297 if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) {
298 handleOwnThenable(promise, maybeThenable);
300 if (then$$1 === undefined) {
301 fulfill(promise, maybeThenable);
302 } else if (isFunction(then$$1)) {
303 handleForeignThenable(promise, maybeThenable, then$$1);
305 fulfill(promise, maybeThenable);
310 function resolve(promise, value) {
311 if (promise === value) {
312 reject(promise, selfFulfillment());
313 } else if (objectOrFunction(value)) {
314 var then$$1 = void 0;
316 then$$1 = value.then;
318 reject(promise, error);
321 handleMaybeThenable(promise, value, then$$1);
323 fulfill(promise, value);
327 function publishRejection(promise) {
328 if (promise._onerror) {
329 promise._onerror(promise._result);
335 function fulfill(promise, value) {
336 if (promise._state !== PENDING) {
340 promise._result = value;
341 promise._state = FULFILLED;
343 if (promise._subscribers.length !== 0) {
344 asap(publish, promise);
348 function reject(promise, reason) {
349 if (promise._state !== PENDING) {
352 promise._state = REJECTED;
353 promise._result = reason;
355 asap(publishRejection, promise);
358 function subscribe(parent, child, onFulfillment, onRejection) {
359 var _subscribers = parent._subscribers;
360 var length = _subscribers.length;
363 parent._onerror = null;
365 _subscribers[length] = child;
366 _subscribers[length + FULFILLED] = onFulfillment;
367 _subscribers[length + REJECTED] = onRejection;
369 if (length === 0 && parent._state) {
370 asap(publish, parent);
374 function publish(promise) {
375 var subscribers = promise._subscribers;
376 var settled = promise._state;
378 if (subscribers.length === 0) {
384 detail = promise._result;
386 for (var i = 0; i < subscribers.length; i += 3) {
387 child = subscribers[i];
388 callback = subscribers[i + settled];
391 invokeCallback(settled, child, callback, detail);
397 promise._subscribers.length = 0;
400 function invokeCallback(settled, promise, callback, detail) {
401 var hasCallback = isFunction(callback),
408 value = callback(detail);
414 if (promise === value) {
415 reject(promise, cannotReturnOwn());
422 if (promise._state !== PENDING) {
424 } else if (hasCallback && succeeded) {
425 resolve(promise, value);
426 } else if (succeeded === false) {
427 reject(promise, error);
428 } else if (settled === FULFILLED) {
429 fulfill(promise, value);
430 } else if (settled === REJECTED) {
431 reject(promise, value);
435 function initializePromise(promise, resolver) {
437 resolver(function resolvePromise(value) {
438 resolve(promise, value);
439 }, function rejectPromise(reason) {
440 reject(promise, reason);
452 function makePromise(promise) {
453 promise[PROMISE_ID] = id++;
454 promise._state = undefined;
455 promise._result = undefined;
456 promise._subscribers = [];
459 function validationError() {
460 return new Error('Array Methods must be provided an Array');
463 var Enumerator = function () {
464 function Enumerator(Constructor, input) {
465 this._instanceConstructor = Constructor;
466 this.promise = new Constructor(noop);
468 if (!this.promise[PROMISE_ID]) {
469 makePromise(this.promise);
472 if (isArray(input)) {
473 this.length = input.length;
474 this._remaining = input.length;
476 this._result = new Array(this.length);
478 if (this.length === 0) {
479 fulfill(this.promise, this._result);
481 this.length = this.length || 0;
482 this._enumerate(input);
483 if (this._remaining === 0) {
484 fulfill(this.promise, this._result);
488 reject(this.promise, validationError());
492 Enumerator.prototype._enumerate = function _enumerate(input) {
493 for (var i = 0; this._state === PENDING && i < input.length; i++) {
494 this._eachEntry(input[i], i);
498 Enumerator.prototype._eachEntry = function _eachEntry(entry, i) {
499 var c = this._instanceConstructor;
500 var resolve$$1 = c.resolve;
503 if (resolve$$1 === resolve$1) {
506 var didError = false;
514 if (_then === then && entry._state !== PENDING) {
515 this._settledAt(entry._state, i, entry._result);
516 } else if (typeof _then !== 'function') {
518 this._result[i] = entry;
519 } else if (c === Promise$2) {
520 var promise = new c(noop);
522 reject(promise, error);
524 handleMaybeThenable(promise, entry, _then);
526 this._willSettleAt(promise, i);
528 this._willSettleAt(new c(function (resolve$$1) {
529 return resolve$$1(entry);
533 this._willSettleAt(resolve$$1(entry), i);
537 Enumerator.prototype._settledAt = function _settledAt(state, i, value) {
538 var promise = this.promise;
541 if (promise._state === PENDING) {
544 if (state === REJECTED) {
545 reject(promise, value);
547 this._result[i] = value;
551 if (this._remaining === 0) {
552 fulfill(promise, this._result);
556 Enumerator.prototype._willSettleAt = function _willSettleAt(promise, i) {
557 var enumerator = this;
559 subscribe(promise, undefined, function (value) {
560 return enumerator._settledAt(FULFILLED, i, value);
561 }, function (reason) {
562 return enumerator._settledAt(REJECTED, i, reason);
570 `Promise.all` accepts an array of promises, and returns a new promise which
571 is fulfilled with an array of fulfillment values for the passed promises, or
572 rejected with the reason of the first passed promise to be rejected. It casts all
573 elements of the passed iterable to promises as it runs this algorithm.
578 let promise1 = resolve(1);
579 let promise2 = resolve(2);
580 let promise3 = resolve(3);
581 let promises = [ promise1, promise2, promise3 ];
583 Promise.all(promises).then(function(array){
584 // The array here would be [ 1, 2, 3 ];
588 If any of the `promises` given to `all` are rejected, the first promise
589 that is rejected will be given as an argument to the returned promises's
590 rejection handler. For example:
595 let promise1 = resolve(1);
596 let promise2 = reject(new Error("2"));
597 let promise3 = reject(new Error("3"));
598 let promises = [ promise1, promise2, promise3 ];
600 Promise.all(promises).then(function(array){
601 // Code here never runs because there are rejected promises!
603 // error.message === "2"
609 @param {Array} entries array of promises
610 @param {String} label optional string for labeling the promise.
612 @return {Promise} promise that is fulfilled when all `promises` have been
613 fulfilled, or rejected if any of them become rejected.
616 function all(entries) {
617 return new Enumerator(this, entries).promise;
621 `Promise.race` returns a new promise which is settled in the same way as the
622 first passed promise to settle.
627 let promise1 = new Promise(function(resolve, reject){
628 setTimeout(function(){
629 resolve('promise 1');
633 let promise2 = new Promise(function(resolve, reject){
634 setTimeout(function(){
635 resolve('promise 2');
639 Promise.race([promise1, promise2]).then(function(result){
640 // result === 'promise 2' because it was resolved before promise1
645 `Promise.race` is deterministic in that only the state of the first
646 settled promise matters. For example, even if other promises given to the
647 `promises` array argument are resolved, but the first settled promise has
648 become rejected before the other promises became fulfilled, the returned
649 promise will become rejected:
652 let promise1 = new Promise(function(resolve, reject){
653 setTimeout(function(){
654 resolve('promise 1');
658 let promise2 = new Promise(function(resolve, reject){
659 setTimeout(function(){
660 reject(new Error('promise 2'));
664 Promise.race([promise1, promise2]).then(function(result){
665 // Code here never runs
667 // reason.message === 'promise 2' because promise 2 became rejected before
668 // promise 1 became fulfilled
672 An example real-world use case is implementing timeouts:
675 Promise.race([ajax('foo.json'), timeout(5000)])
680 @param {Array} promises array of promises to observe
682 @return {Promise} a promise which settles in the same way as the first passed
685 function race(entries) {
686 /*jshint validthis:true */
687 var Constructor = this;
689 if (!isArray(entries)) {
690 return new Constructor(function (_, reject) {
691 return reject(new TypeError('You must pass an array to race.'));
694 return new Constructor(function (resolve, reject) {
695 var length = entries.length;
696 for (var i = 0; i < length; i++) {
697 Constructor.resolve(entries[i]).then(resolve, reject);
704 `Promise.reject` returns a promise rejected with the passed `reason`.
705 It is shorthand for the following:
708 let promise = new Promise(function(resolve, reject){
709 reject(new Error('WHOOPS'));
712 promise.then(function(value){
713 // Code here doesn't run because the promise is rejected!
715 // reason.message === 'WHOOPS'
719 Instead of writing the above, your code now simply becomes the following:
722 let promise = Promise.reject(new Error('WHOOPS'));
724 promise.then(function(value){
725 // Code here doesn't run because the promise is rejected!
727 // reason.message === 'WHOOPS'
733 @param {Any} reason value that the returned promise will be rejected with.
735 @return {Promise} a promise rejected with the given `reason`.
737 function reject$1(reason) {
738 /*jshint validthis:true */
739 var Constructor = this;
740 var promise = new Constructor(noop);
741 reject(promise, reason);
745 function needsResolver() {
746 throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
749 function needsNew() {
750 throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
754 Promise objects represent the eventual result of an asynchronous operation. The
755 primary way of interacting with a promise is through its `then` method, which
756 registers callbacks to receive either a promise's eventual value or the reason
757 why the promise cannot be fulfilled.
762 - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
763 - `thenable` is an object or function that defines a `then` method.
764 - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
765 - `exception` is a value that is thrown using the throw statement.
766 - `reason` is a value that indicates why a promise was rejected.
767 - `settled` the final resting state of a promise, fulfilled or rejected.
769 A promise can be in one of three states: pending, fulfilled, or rejected.
771 Promises that are fulfilled have a fulfillment value and are in the fulfilled
772 state. Promises that are rejected have a rejection reason and are in the
773 rejected state. A fulfillment value is never a thenable.
775 Promises can also be said to *resolve* a value. If this value is also a
776 promise, then the original promise's settled state will match the value's
777 settled state. So a promise that *resolves* a promise that rejects will
778 itself reject, and a promise that *resolves* a promise that fulfills will
786 let promise = new Promise(function(resolve, reject) {
794 promise.then(function(value) {
796 }, function(reason) {
804 Promises shine when abstracting away asynchronous interactions such as
808 function getJSON(url) {
809 return new Promise(function(resolve, reject){
810 let xhr = new XMLHttpRequest();
812 xhr.open('GET', url);
813 xhr.onreadystatechange = handler;
814 xhr.responseType = 'json';
815 xhr.setRequestHeader('Accept', 'application/json');
819 if (this.readyState === this.DONE) {
820 if (this.status === 200) {
821 resolve(this.response);
823 reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
830 getJSON('/posts.json').then(function(json) {
832 }, function(reason) {
837 Unlike callbacks, promises are great composable primitives.
843 ]).then(function(values){
844 values[0] // => postsJSON
845 values[1] // => commentsJSON
852 @param {Function} resolver
857 var Promise$2 = function () {
858 function Promise(resolver) {
859 this[PROMISE_ID] = nextId();
860 this._result = this._state = undefined;
861 this._subscribers = [];
863 if (noop !== resolver) {
864 typeof resolver !== 'function' && needsResolver();
865 this instanceof Promise ? initializePromise(this, resolver) : needsNew();
870 The primary way of interacting with a promise is through its `then` method,
871 which registers callbacks to receive either a promise's eventual value or the
872 reason why the promise cannot be fulfilled.
874 findUser().then(function(user){
877 // user is unavailable, and you are given the reason why
882 The return value of `then` is itself a promise. This second, 'downstream'
883 promise is resolved with the return value of the first promise's fulfillment
884 or rejection handler, or rejected if the handler throws an exception.
886 findUser().then(function (user) {
888 }, function (reason) {
889 return 'default name';
890 }).then(function (userName) {
891 // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
892 // will be `'default name'`
894 findUser().then(function (user) {
895 throw new Error('Found user, but still unhappy');
896 }, function (reason) {
897 throw new Error('`findUser` rejected and we're unhappy');
898 }).then(function (value) {
900 }, function (reason) {
901 // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
902 // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
905 If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
907 findUser().then(function (user) {
908 throw new PedagogicalException('Upstream error');
909 }).then(function (value) {
911 }).then(function (value) {
913 }, function (reason) {
914 // The `PedgagocialException` is propagated all the way down to here
919 Sometimes the value you want to propagate to a downstream promise can only be
920 retrieved asynchronously. This can be achieved by returning a promise in the
921 fulfillment or rejection handler. The downstream promise will then be pending
922 until the returned promise is settled. This is called *assimilation*.
924 findUser().then(function (user) {
925 return findCommentsByAuthor(user);
926 }).then(function (comments) {
927 // The user's comments are now available
930 If the assimliated promise rejects, then the downstream promise will also reject.
932 findUser().then(function (user) {
933 return findCommentsByAuthor(user);
934 }).then(function (comments) {
935 // If `findCommentsByAuthor` fulfills, we'll have the value here
936 }, function (reason) {
937 // If `findCommentsByAuthor` rejects, we'll have the reason here
946 result = findResult();
954 findResult(function(result, err){
964 findResult().then(function(result){
976 author = findAuthor();
977 books = findBooksByAuthor(author);
985 function foundBooks(books) {
987 function failure(reason) {
989 findAuthor(function(author, err){
995 findBoooksByAuthor(author, function(books, err) {
1016 then(findBooksByAuthor).
1017 then(function(books){
1019 }).catch(function(reason){
1020 // something went wrong
1024 @param {Function} onFulfilled
1025 @param {Function} onRejected
1031 `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
1032 as the catch block of a try/catch statement.
1034 function findAuthor(){
1035 throw new Error('couldn't find that author');
1041 // something went wrong
1043 // async with promises
1044 findAuthor().catch(function(reason){
1045 // something went wrong
1049 @param {Function} onRejection
1055 Promise.prototype.catch = function _catch(onRejection) {
1056 return this.then(null, onRejection);
1060 `finally` will be invoked regardless of the promise's fate just as native
1061 try/catch/finally behaves
1063 Synchronous example:
1067 if (Math.random() > 0.5) {
1070 return new Author();
1074 return findAuthor(); // succeed or fail
1076 return findOtherAuther();
1079 // doesn't affect the return value
1083 Asynchronous example:
1086 findAuthor().catch(function(reason){
1087 return findOtherAuther();
1088 }).finally(function(){
1089 // author was either found, or not
1094 @param {Function} callback
1099 Promise.prototype.finally = function _finally(callback) {
1101 var constructor = promise.constructor;
1103 if (isFunction(callback)) {
1104 return promise.then(function (value) {
1105 return constructor.resolve(callback()).then(function () {
1108 }, function (reason) {
1109 return constructor.resolve(callback()).then(function () {
1115 return promise.then(callback, callback);
1121 Promise$2.prototype.then = then;
1122 Promise$2.all = all;
1123 Promise$2.race = race;
1124 Promise$2.resolve = resolve$1;
1125 Promise$2.reject = reject$1;
1126 Promise$2._setScheduler = setScheduler;
1127 Promise$2._setAsap = setAsap;
1128 Promise$2._asap = asap;
1131 function polyfill() {
1134 if (typeof global !== 'undefined') {
1136 } else if (typeof self !== 'undefined') {
1140 local = Function('return this')();
1142 throw new Error('polyfill failed because global object is unavailable in this environment');
1146 var P = local.Promise;
1149 var promiseToString = null;
1151 promiseToString = Object.prototype.toString.call(P.resolve());
1156 if (promiseToString === '[object Promise]' && !P.cast) {
1161 local.Promise = Promise$2;
1165 Promise$2.polyfill = polyfill;
1166 Promise$2.Promise = Promise$2;
1168 Promise$2.polyfill();
1176 //# sourceMappingURL=es6-promise.auto.map