| !function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.Promise=e():"undefined"!=typeof global?global.Promise=e():"undefined"!=typeof self&&(self.Promise=e())}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ |
| /** @license MIT License (c) copyright 2010-2014 original author or authors */ |
| /** @author Brian Cavalier */ |
| /** @author John Hann */ |
| |
| /** |
| * ES6 global Promise shim |
| */ |
| var unhandledRejections = require('../lib/decorators/unhandledRejection'); |
| var PromiseConstructor = unhandledRejections(require('../lib/Promise')); |
| |
| module.exports = typeof global != 'undefined' ? (global.Promise = PromiseConstructor) |
| : typeof self != 'undefined' ? (self.Promise = PromiseConstructor) |
| : PromiseConstructor; |
| |
| },{"../lib/Promise":2,"../lib/decorators/unhandledRejection":4}],2:[function(require,module,exports){ |
| /** @license MIT License (c) copyright 2010-2014 original author or authors */ |
| /** @author Brian Cavalier */ |
| /** @author John Hann */ |
| |
| (function(define) { 'use strict'; |
| define(function (require) { |
| |
| var makePromise = require('./makePromise'); |
| var Scheduler = require('./Scheduler'); |
| var async = require('./env').asap; |
| |
| return makePromise({ |
| scheduler: new Scheduler(async) |
| }); |
| |
| }); |
| })(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }); |
| |
| },{"./Scheduler":3,"./env":5,"./makePromise":7}],3:[function(require,module,exports){ |
| /** @license MIT License (c) copyright 2010-2014 original author or authors */ |
| /** @author Brian Cavalier */ |
| /** @author John Hann */ |
| |
| (function(define) { 'use strict'; |
| define(function() { |
| |
| // Credit to Twisol (https://github.com/Twisol) for suggesting |
| // this type of extensible queue + trampoline approach for next-tick conflation. |
| |
| /** |
| * Async task scheduler |
| * @param {function} async function to schedule a single async function |
| * @constructor |
| */ |
| function Scheduler(async) { |
| this._async = async; |
| this._running = false; |
| |
| this._queue = this; |
| this._queueLen = 0; |
| this._afterQueue = {}; |
| this._afterQueueLen = 0; |
| |
| var self = this; |
| this.drain = function() { |
| self._drain(); |
| }; |
| } |
| |
| /** |
| * Enqueue a task |
| * @param {{ run:function }} task |
| */ |
| Scheduler.prototype.enqueue = function(task) { |
| this._queue[this._queueLen++] = task; |
| this.run(); |
| }; |
| |
| /** |
| * Enqueue a task to run after the main task queue |
| * @param {{ run:function }} task |
| */ |
| Scheduler.prototype.afterQueue = function(task) { |
| this._afterQueue[this._afterQueueLen++] = task; |
| this.run(); |
| }; |
| |
| Scheduler.prototype.run = function() { |
| if (!this._running) { |
| this._running = true; |
| this._async(this.drain); |
| } |
| }; |
| |
| /** |
| * Drain the handler queue entirely, and then the after queue |
| */ |
| Scheduler.prototype._drain = function() { |
| var i = 0; |
| for (; i < this._queueLen; ++i) { |
| this._queue[i].run(); |
| this._queue[i] = void 0; |
| } |
| |
| this._queueLen = 0; |
| this._running = false; |
| |
| for (i = 0; i < this._afterQueueLen; ++i) { |
| this._afterQueue[i].run(); |
| this._afterQueue[i] = void 0; |
| } |
| |
| this._afterQueueLen = 0; |
| }; |
| |
| return Scheduler; |
| |
| }); |
| }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); |
| |
| },{}],4:[function(require,module,exports){ |
| /** @license MIT License (c) copyright 2010-2014 original author or authors */ |
| /** @author Brian Cavalier */ |
| /** @author John Hann */ |
| |
| (function(define) { 'use strict'; |
| define(function(require) { |
| |
| var setTimer = require('../env').setTimer; |
| var format = require('../format'); |
| |
| return function unhandledRejection(Promise) { |
| |
| var logError = noop; |
| var logInfo = noop; |
| var localConsole; |
| |
| if(typeof console !== 'undefined') { |
| // Alias console to prevent things like uglify's drop_console option from |
| // removing console.log/error. Unhandled rejections fall into the same |
| // category as uncaught exceptions, and build tools shouldn't silence them. |
| localConsole = console; |
| logError = typeof localConsole.error !== 'undefined' |
| ? function (e) { localConsole.error(e); } |
| : function (e) { localConsole.log(e); }; |
| |
| logInfo = typeof localConsole.info !== 'undefined' |
| ? function (e) { localConsole.info(e); } |
| : function (e) { localConsole.log(e); }; |
| } |
| |
| Promise.onPotentiallyUnhandledRejection = function(rejection) { |
| enqueue(report, rejection); |
| }; |
| |
| Promise.onPotentiallyUnhandledRejectionHandled = function(rejection) { |
| enqueue(unreport, rejection); |
| }; |
| |
| Promise.onFatalRejection = function(rejection) { |
| enqueue(throwit, rejection.value); |
| }; |
| |
| var tasks = []; |
| var reported = []; |
| var running = null; |
| |
| function report(r) { |
| if(!r.handled) { |
| reported.push(r); |
| logError('Potentially unhandled rejection [' + r.id + '] ' + format.formatError(r.value)); |
| } |
| } |
| |
| function unreport(r) { |
| var i = reported.indexOf(r); |
| if(i >= 0) { |
| reported.splice(i, 1); |
| logInfo('Handled previous rejection [' + r.id + '] ' + format.formatObject(r.value)); |
| } |
| } |
| |
| function enqueue(f, x) { |
| tasks.push(f, x); |
| if(running === null) { |
| running = setTimer(flush, 0); |
| } |
| } |
| |
| function flush() { |
| running = null; |
| while(tasks.length > 0) { |
| tasks.shift()(tasks.shift()); |
| } |
| } |
| |
| return Promise; |
| }; |
| |
| function throwit(e) { |
| throw e; |
| } |
| |
| function noop() {} |
| |
| }); |
| }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); })); |
| |
| },{"../env":5,"../format":6}],5:[function(require,module,exports){ |
| /** @license MIT License (c) copyright 2010-2014 original author or authors */ |
| /** @author Brian Cavalier */ |
| /** @author John Hann */ |
| |
| /*global process,document,setTimeout,clearTimeout,MutationObserver,WebKitMutationObserver*/ |
| (function(define) { 'use strict'; |
| define(function(require) { |
| /*jshint maxcomplexity:6*/ |
| |
| // Sniff "best" async scheduling option |
| // Prefer process.nextTick or MutationObserver, then check for |
| // setTimeout, and finally vertx, since its the only env that doesn't |
| // have setTimeout |
| |
| var MutationObs; |
| var capturedSetTimeout = typeof setTimeout !== 'undefined' && setTimeout; |
| |
| // Default env |
| var setTimer = function(f, ms) { return setTimeout(f, ms); }; |
| var clearTimer = function(t) { return clearTimeout(t); }; |
| var asap = function (f) { return capturedSetTimeout(f, 0); }; |
| |
| // Detect specific env |
| if (isNode()) { // Node |
| asap = function (f) { return process.nextTick(f); }; |
| |
| } else if (MutationObs = hasMutationObserver()) { // Modern browser |
| asap = initMutationObserver(MutationObs); |
| |
| } else if (!capturedSetTimeout) { // vert.x |
| var vertxRequire = require; |
| var vertx = vertxRequire('vertx'); |
| setTimer = function (f, ms) { return vertx.setTimer(ms, f); }; |
| clearTimer = vertx.cancelTimer; |
| asap = vertx.runOnLoop || vertx.runOnContext; |
| } |
| |
| return { |
| setTimer: setTimer, |
| clearTimer: clearTimer, |
| asap: asap |
| }; |
| |
| function isNode () { |
| return typeof process !== 'undefined' && |
| Object.prototype.toString.call(process) === '[object process]'; |
| } |
| |
| function hasMutationObserver () { |
| return (typeof MutationObserver !== 'undefined' && MutationObserver) || |
| (typeof WebKitMutationObserver !== 'undefined' && WebKitMutationObserver); |
| } |
| |
| function initMutationObserver(MutationObserver) { |
| var scheduled; |
| var node = document.createTextNode(''); |
| var o = new MutationObserver(run); |
| o.observe(node, { characterData: true }); |
| |
| function run() { |
| var f = scheduled; |
| scheduled = void 0; |
| f(); |
| } |
| |
| var i = 0; |
| return function (f) { |
| scheduled = f; |
| node.data = (i ^= 1); |
| }; |
| } |
| }); |
| }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); })); |
| |
| },{}],6:[function(require,module,exports){ |
| /** @license MIT License (c) copyright 2010-2014 original author or authors */ |
| /** @author Brian Cavalier */ |
| /** @author John Hann */ |
| |
| (function(define) { 'use strict'; |
| define(function() { |
| |
| return { |
| formatError: formatError, |
| formatObject: formatObject, |
| tryStringify: tryStringify |
| }; |
| |
| /** |
| * Format an error into a string. If e is an Error and has a stack property, |
| * it's returned. Otherwise, e is formatted using formatObject, with a |
| * warning added about e not being a proper Error. |
| * @param {*} e |
| * @returns {String} formatted string, suitable for output to developers |
| */ |
| function formatError(e) { |
| var s = typeof e === 'object' && e !== null && (e.stack || e.message) ? e.stack || e.message : formatObject(e); |
| return e instanceof Error ? s : s + ' (WARNING: non-Error used)'; |
| } |
| |
| /** |
| * Format an object, detecting "plain" objects and running them through |
| * JSON.stringify if possible. |
| * @param {Object} o |
| * @returns {string} |
| */ |
| function formatObject(o) { |
| var s = String(o); |
| if(s === '[object Object]' && typeof JSON !== 'undefined') { |
| s = tryStringify(o, s); |
| } |
| return s; |
| } |
| |
| /** |
| * Try to return the result of JSON.stringify(x). If that fails, return |
| * defaultValue |
| * @param {*} x |
| * @param {*} defaultValue |
| * @returns {String|*} JSON.stringify(x) or defaultValue |
| */ |
| function tryStringify(x, defaultValue) { |
| try { |
| return JSON.stringify(x); |
| } catch(e) { |
| return defaultValue; |
| } |
| } |
| |
| }); |
| }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); |
| |
| },{}],7:[function(require,module,exports){ |
| /** @license MIT License (c) copyright 2010-2014 original author or authors */ |
| /** @author Brian Cavalier */ |
| /** @author John Hann */ |
| |
| (function(define) { 'use strict'; |
| define(function() { |
| |
| return function makePromise(environment) { |
| |
| var tasks = environment.scheduler; |
| var emitRejection = initEmitRejection(); |
| |
| var objectCreate = Object.create || |
| function(proto) { |
| function Child() {} |
| Child.prototype = proto; |
| return new Child(); |
| }; |
| |
| /** |
| * Create a promise whose fate is determined by resolver |
| * @constructor |
| * @returns {Promise} promise |
| * @name Promise |
| */ |
| function Promise(resolver, handler) { |
| this._handler = resolver === Handler ? handler : init(resolver); |
| } |
| |
| /** |
| * Run the supplied resolver |
| * @param resolver |
| * @returns {Pending} |
| */ |
| function init(resolver) { |
| var handler = new Pending(); |
| |
| try { |
| resolver(promiseResolve, promiseReject, promiseNotify); |
| } catch (e) { |
| promiseReject(e); |
| } |
| |
| return handler; |
| |
| /** |
| * Transition from pre-resolution state to post-resolution state, notifying |
| * all listeners of the ultimate fulfillment or rejection |
| * @param {*} x resolution value |
| */ |
| function promiseResolve (x) { |
| handler.resolve(x); |
| } |
| /** |
| * Reject this promise with reason, which will be used verbatim |
| * @param {Error|*} reason rejection reason, strongly suggested |
| * to be an Error type |
| */ |
| function promiseReject (reason) { |
| handler.reject(reason); |
| } |
| |
| /** |
| * @deprecated |
| * Issue a progress event, notifying all progress listeners |
| * @param {*} x progress event payload to pass to all listeners |
| */ |
| function promiseNotify (x) { |
| handler.notify(x); |
| } |
| } |
| |
| // Creation |
| |
| Promise.resolve = resolve; |
| Promise.reject = reject; |
| Promise.never = never; |
| |
| Promise._defer = defer; |
| Promise._handler = getHandler; |
| |
| /** |
| * Returns a trusted promise. If x is already a trusted promise, it is |
| * returned, otherwise returns a new trusted Promise which follows x. |
| * @param {*} x |
| * @return {Promise} promise |
| */ |
| function resolve(x) { |
| return isPromise(x) ? x |
| : new Promise(Handler, new Async(getHandler(x))); |
| } |
| |
| /** |
| * Return a reject promise with x as its reason (x is used verbatim) |
| * @param {*} x |
| * @returns {Promise} rejected promise |
| */ |
| function reject(x) { |
| return new Promise(Handler, new Async(new Rejected(x))); |
| } |
| |
| /** |
| * Return a promise that remains pending forever |
| * @returns {Promise} forever-pending promise. |
| */ |
| function never() { |
| return foreverPendingPromise; // Should be frozen |
| } |
| |
| /** |
| * Creates an internal {promise, resolver} pair |
| * @private |
| * @returns {Promise} |
| */ |
| function defer() { |
| return new Promise(Handler, new Pending()); |
| } |
| |
| // Transformation and flow control |
| |
| /** |
| * Transform this promise's fulfillment value, returning a new Promise |
| * for the transformed result. If the promise cannot be fulfilled, onRejected |
| * is called with the reason. onProgress *may* be called with updates toward |
| * this promise's fulfillment. |
| * @param {function=} onFulfilled fulfillment handler |
| * @param {function=} onRejected rejection handler |
| * @param {function=} onProgress @deprecated progress handler |
| * @return {Promise} new promise |
| */ |
| Promise.prototype.then = function(onFulfilled, onRejected, onProgress) { |
| var parent = this._handler; |
| var state = parent.join().state(); |
| |
| if ((typeof onFulfilled !== 'function' && state > 0) || |
| (typeof onRejected !== 'function' && state < 0)) { |
| // Short circuit: value will not change, simply share handler |
| return new this.constructor(Handler, parent); |
| } |
| |
| var p = this._beget(); |
| var child = p._handler; |
| |
| parent.chain(child, parent.receiver, onFulfilled, onRejected, onProgress); |
| |
| return p; |
| }; |
| |
| /** |
| * If this promise cannot be fulfilled due to an error, call onRejected to |
| * handle the error. Shortcut for .then(undefined, onRejected) |
| * @param {function?} onRejected |
| * @return {Promise} |
| */ |
| Promise.prototype['catch'] = function(onRejected) { |
| return this.then(void 0, onRejected); |
| }; |
| |
| /** |
| * Creates a new, pending promise of the same type as this promise |
| * @private |
| * @returns {Promise} |
| */ |
| Promise.prototype._beget = function() { |
| return begetFrom(this._handler, this.constructor); |
| }; |
| |
| function begetFrom(parent, Promise) { |
| var child = new Pending(parent.receiver, parent.join().context); |
| return new Promise(Handler, child); |
| } |
| |
| // Array combinators |
| |
| Promise.all = all; |
| Promise.race = race; |
| Promise._traverse = traverse; |
| |
| /** |
| * Return a promise that will fulfill when all promises in the |
| * input array have fulfilled, or will reject when one of the |
| * promises rejects. |
| * @param {array} promises array of promises |
| * @returns {Promise} promise for array of fulfillment values |
| */ |
| function all(promises) { |
| return traverseWith(snd, null, promises); |
| } |
| |
| /** |
| * Array<Promise<X>> -> Promise<Array<f(X)>> |
| * @private |
| * @param {function} f function to apply to each promise's value |
| * @param {Array} promises array of promises |
| * @returns {Promise} promise for transformed values |
| */ |
| function traverse(f, promises) { |
| return traverseWith(tryCatch2, f, promises); |
| } |
| |
| function traverseWith(tryMap, f, promises) { |
| var handler = typeof f === 'function' ? mapAt : settleAt; |
| |
| var resolver = new Pending(); |
| var pending = promises.length >>> 0; |
| var results = new Array(pending); |
| |
| for (var i = 0, x; i < promises.length && !resolver.resolved; ++i) { |
| x = promises[i]; |
| |
| if (x === void 0 && !(i in promises)) { |
| --pending; |
| continue; |
| } |
| |
| traverseAt(promises, handler, i, x, resolver); |
| } |
| |
| if(pending === 0) { |
| resolver.become(new Fulfilled(results)); |
| } |
| |
| return new Promise(Handler, resolver); |
| |
| function mapAt(i, x, resolver) { |
| if(!resolver.resolved) { |
| traverseAt(promises, settleAt, i, tryMap(f, x, i), resolver); |
| } |
| } |
| |
| function settleAt(i, x, resolver) { |
| results[i] = x; |
| if(--pending === 0) { |
| resolver.become(new Fulfilled(results)); |
| } |
| } |
| } |
| |
| function traverseAt(promises, handler, i, x, resolver) { |
| if (maybeThenable(x)) { |
| var h = getHandlerMaybeThenable(x); |
| var s = h.state(); |
| |
| if (s === 0) { |
| h.fold(handler, i, void 0, resolver); |
| } else if (s > 0) { |
| handler(i, h.value, resolver); |
| } else { |
| resolver.become(h); |
| visitRemaining(promises, i+1, h); |
| } |
| } else { |
| handler(i, x, resolver); |
| } |
| } |
| |
| Promise._visitRemaining = visitRemaining; |
| function visitRemaining(promises, start, handler) { |
| for(var i=start; i<promises.length; ++i) { |
| markAsHandled(getHandler(promises[i]), handler); |
| } |
| } |
| |
| function markAsHandled(h, handler) { |
| if(h === handler) { |
| return; |
| } |
| |
| var s = h.state(); |
| if(s === 0) { |
| h.visit(h, void 0, h._unreport); |
| } else if(s < 0) { |
| h._unreport(); |
| } |
| } |
| |
| /** |
| * Fulfill-reject competitive race. Return a promise that will settle |
| * to the same state as the earliest input promise to settle. |
| * |
| * WARNING: The ES6 Promise spec requires that race()ing an empty array |
| * must return a promise that is pending forever. This implementation |
| * returns a singleton forever-pending promise, the same singleton that is |
| * returned by Promise.never(), thus can be checked with === |
| * |
| * @param {array} promises array of promises to race |
| * @returns {Promise} if input is non-empty, a promise that will settle |
| * to the same outcome as the earliest input promise to settle. if empty |
| * is empty, returns a promise that will never settle. |
| */ |
| function race(promises) { |
| if(typeof promises !== 'object' || promises === null) { |
| return reject(new TypeError('non-iterable passed to race()')); |
| } |
| |
| // Sigh, race([]) is untestable unless we return *something* |
| // that is recognizable without calling .then() on it. |
| return promises.length === 0 ? never() |
| : promises.length === 1 ? resolve(promises[0]) |
| : runRace(promises); |
| } |
| |
| function runRace(promises) { |
| var resolver = new Pending(); |
| var i, x, h; |
| for(i=0; i<promises.length; ++i) { |
| x = promises[i]; |
| if (x === void 0 && !(i in promises)) { |
| continue; |
| } |
| |
| h = getHandler(x); |
| if(h.state() !== 0) { |
| resolver.become(h); |
| visitRemaining(promises, i+1, h); |
| break; |
| } else { |
| h.visit(resolver, resolver.resolve, resolver.reject); |
| } |
| } |
| return new Promise(Handler, resolver); |
| } |
| |
| // Promise internals |
| // Below this, everything is @private |
| |
| /** |
| * Get an appropriate handler for x, without checking for cycles |
| * @param {*} x |
| * @returns {object} handler |
| */ |
| function getHandler(x) { |
| if(isPromise(x)) { |
| return x._handler.join(); |
| } |
| return maybeThenable(x) ? getHandlerUntrusted(x) : new Fulfilled(x); |
| } |
| |
| /** |
| * Get a handler for thenable x. |
| * NOTE: You must only call this if maybeThenable(x) == true |
| * @param {object|function|Promise} x |
| * @returns {object} handler |
| */ |
| function getHandlerMaybeThenable(x) { |
| return isPromise(x) ? x._handler.join() : getHandlerUntrusted(x); |
| } |
| |
| /** |
| * Get a handler for potentially untrusted thenable x |
| * @param {*} x |
| * @returns {object} handler |
| */ |
| function getHandlerUntrusted(x) { |
| try { |
| var untrustedThen = x.then; |
| return typeof untrustedThen === 'function' |
| ? new Thenable(untrustedThen, x) |
| : new Fulfilled(x); |
| } catch(e) { |
| return new Rejected(e); |
| } |
| } |
| |
| /** |
| * Handler for a promise that is pending forever |
| * @constructor |
| */ |
| function Handler() {} |
| |
| Handler.prototype.when |
| = Handler.prototype.become |
| = Handler.prototype.notify // deprecated |
| = Handler.prototype.fail |
| = Handler.prototype._unreport |
| = Handler.prototype._report |
| = noop; |
| |
| Handler.prototype._state = 0; |
| |
| Handler.prototype.state = function() { |
| return this._state; |
| }; |
| |
| /** |
| * Recursively collapse handler chain to find the handler |
| * nearest to the fully resolved value. |
| * @returns {object} handler nearest the fully resolved value |
| */ |
| Handler.prototype.join = function() { |
| var h = this; |
| while(h.handler !== void 0) { |
| h = h.handler; |
| } |
| return h; |
| }; |
| |
| Handler.prototype.chain = function(to, receiver, fulfilled, rejected, progress) { |
| this.when({ |
| resolver: to, |
| receiver: receiver, |
| fulfilled: fulfilled, |
| rejected: rejected, |
| progress: progress |
| }); |
| }; |
| |
| Handler.prototype.visit = function(receiver, fulfilled, rejected, progress) { |
| this.chain(failIfRejected, receiver, fulfilled, rejected, progress); |
| }; |
| |
| Handler.prototype.fold = function(f, z, c, to) { |
| this.when(new Fold(f, z, c, to)); |
| }; |
| |
| /** |
| * Handler that invokes fail() on any handler it becomes |
| * @constructor |
| */ |
| function FailIfRejected() {} |
| |
| inherit(Handler, FailIfRejected); |
| |
| FailIfRejected.prototype.become = function(h) { |
| h.fail(); |
| }; |
| |
| var failIfRejected = new FailIfRejected(); |
| |
| /** |
| * Handler that manages a queue of consumers waiting on a pending promise |
| * @constructor |
| */ |
| function Pending(receiver, inheritedContext) { |
| Promise.createContext(this, inheritedContext); |
| |
| this.consumers = void 0; |
| this.receiver = receiver; |
| this.handler = void 0; |
| this.resolved = false; |
| } |
| |
| inherit(Handler, Pending); |
| |
| Pending.prototype._state = 0; |
| |
| Pending.prototype.resolve = function(x) { |
| this.become(getHandler(x)); |
| }; |
| |
| Pending.prototype.reject = function(x) { |
| if(this.resolved) { |
| return; |
| } |
| |
| this.become(new Rejected(x)); |
| }; |
| |
| Pending.prototype.join = function() { |
| if (!this.resolved) { |
| return this; |
| } |
| |
| var h = this; |
| |
| while (h.handler !== void 0) { |
| h = h.handler; |
| if (h === this) { |
| return this.handler = cycle(); |
| } |
| } |
| |
| return h; |
| }; |
| |
| Pending.prototype.run = function() { |
| var q = this.consumers; |
| var handler = this.handler; |
| this.handler = this.handler.join(); |
| this.consumers = void 0; |
| |
| for (var i = 0; i < q.length; ++i) { |
| handler.when(q[i]); |
| } |
| }; |
| |
| Pending.prototype.become = function(handler) { |
| if(this.resolved) { |
| return; |
| } |
| |
| this.resolved = true; |
| this.handler = handler; |
| if(this.consumers !== void 0) { |
| tasks.enqueue(this); |
| } |
| |
| if(this.context !== void 0) { |
| handler._report(this.context); |
| } |
| }; |
| |
| Pending.prototype.when = function(continuation) { |
| if(this.resolved) { |
| tasks.enqueue(new ContinuationTask(continuation, this.handler)); |
| } else { |
| if(this.consumers === void 0) { |
| this.consumers = [continuation]; |
| } else { |
| this.consumers.push(continuation); |
| } |
| } |
| }; |
| |
| /** |
| * @deprecated |
| */ |
| Pending.prototype.notify = function(x) { |
| if(!this.resolved) { |
| tasks.enqueue(new ProgressTask(x, this)); |
| } |
| }; |
| |
| Pending.prototype.fail = function(context) { |
| var c = typeof context === 'undefined' ? this.context : context; |
| this.resolved && this.handler.join().fail(c); |
| }; |
| |
| Pending.prototype._report = function(context) { |
| this.resolved && this.handler.join()._report(context); |
| }; |
| |
| Pending.prototype._unreport = function() { |
| this.resolved && this.handler.join()._unreport(); |
| }; |
| |
| /** |
| * Wrap another handler and force it into a future stack |
| * @param {object} handler |
| * @constructor |
| */ |
| function Async(handler) { |
| this.handler = handler; |
| } |
| |
| inherit(Handler, Async); |
| |
| Async.prototype.when = function(continuation) { |
| tasks.enqueue(new ContinuationTask(continuation, this)); |
| }; |
| |
| Async.prototype._report = function(context) { |
| this.join()._report(context); |
| }; |
| |
| Async.prototype._unreport = function() { |
| this.join()._unreport(); |
| }; |
| |
| /** |
| * Handler that wraps an untrusted thenable and assimilates it in a future stack |
| * @param {function} then |
| * @param {{then: function}} thenable |
| * @constructor |
| */ |
| function Thenable(then, thenable) { |
| Pending.call(this); |
| tasks.enqueue(new AssimilateTask(then, thenable, this)); |
| } |
| |
| inherit(Pending, Thenable); |
| |
| /** |
| * Handler for a fulfilled promise |
| * @param {*} x fulfillment value |
| * @constructor |
| */ |
| function Fulfilled(x) { |
| Promise.createContext(this); |
| this.value = x; |
| } |
| |
| inherit(Handler, Fulfilled); |
| |
| Fulfilled.prototype._state = 1; |
| |
| Fulfilled.prototype.fold = function(f, z, c, to) { |
| runContinuation3(f, z, this, c, to); |
| }; |
| |
| Fulfilled.prototype.when = function(cont) { |
| runContinuation1(cont.fulfilled, this, cont.receiver, cont.resolver); |
| }; |
| |
| var errorId = 0; |
| |
| /** |
| * Handler for a rejected promise |
| * @param {*} x rejection reason |
| * @constructor |
| */ |
| function Rejected(x) { |
| Promise.createContext(this); |
| |
| this.id = ++errorId; |
| this.value = x; |
| this.handled = false; |
| this.reported = false; |
| |
| this._report(); |
| } |
| |
| inherit(Handler, Rejected); |
| |
| Rejected.prototype._state = -1; |
| |
| Rejected.prototype.fold = function(f, z, c, to) { |
| to.become(this); |
| }; |
| |
| Rejected.prototype.when = function(cont) { |
| if(typeof cont.rejected === 'function') { |
| this._unreport(); |
| } |
| runContinuation1(cont.rejected, this, cont.receiver, cont.resolver); |
| }; |
| |
| Rejected.prototype._report = function(context) { |
| tasks.afterQueue(new ReportTask(this, context)); |
| }; |
| |
| Rejected.prototype._unreport = function() { |
| if(this.handled) { |
| return; |
| } |
| this.handled = true; |
| tasks.afterQueue(new UnreportTask(this)); |
| }; |
| |
| Rejected.prototype.fail = function(context) { |
| this.reported = true; |
| emitRejection('unhandledRejection', this); |
| Promise.onFatalRejection(this, context === void 0 ? this.context : context); |
| }; |
| |
| function ReportTask(rejection, context) { |
| this.rejection = rejection; |
| this.context = context; |
| } |
| |
| ReportTask.prototype.run = function() { |
| if(!this.rejection.handled && !this.rejection.reported) { |
| this.rejection.reported = true; |
| emitRejection('unhandledRejection', this.rejection) || |
| Promise.onPotentiallyUnhandledRejection(this.rejection, this.context); |
| } |
| }; |
| |
| function UnreportTask(rejection) { |
| this.rejection = rejection; |
| } |
| |
| UnreportTask.prototype.run = function() { |
| if(this.rejection.reported) { |
| emitRejection('rejectionHandled', this.rejection) || |
| Promise.onPotentiallyUnhandledRejectionHandled(this.rejection); |
| } |
| }; |
| |
| // Unhandled rejection hooks |
| // By default, everything is a noop |
| |
| Promise.createContext |
| = Promise.enterContext |
| = Promise.exitContext |
| = Promise.onPotentiallyUnhandledRejection |
| = Promise.onPotentiallyUnhandledRejectionHandled |
| = Promise.onFatalRejection |
| = noop; |
| |
| // Errors and singletons |
| |
| var foreverPendingHandler = new Handler(); |
| var foreverPendingPromise = new Promise(Handler, foreverPendingHandler); |
| |
| function cycle() { |
| return new Rejected(new TypeError('Promise cycle')); |
| } |
| |
| // Task runners |
| |
| /** |
| * Run a single consumer |
| * @constructor |
| */ |
| function ContinuationTask(continuation, handler) { |
| this.continuation = continuation; |
| this.handler = handler; |
| } |
| |
| ContinuationTask.prototype.run = function() { |
| this.handler.join().when(this.continuation); |
| }; |
| |
| /** |
| * Run a queue of progress handlers |
| * @constructor |
| */ |
| function ProgressTask(value, handler) { |
| this.handler = handler; |
| this.value = value; |
| } |
| |
| ProgressTask.prototype.run = function() { |
| var q = this.handler.consumers; |
| if(q === void 0) { |
| return; |
| } |
| |
| for (var c, i = 0; i < q.length; ++i) { |
| c = q[i]; |
| runNotify(c.progress, this.value, this.handler, c.receiver, c.resolver); |
| } |
| }; |
| |
| /** |
| * Assimilate a thenable, sending it's value to resolver |
| * @param {function} then |
| * @param {object|function} thenable |
| * @param {object} resolver |
| * @constructor |
| */ |
| function AssimilateTask(then, thenable, resolver) { |
| this._then = then; |
| this.thenable = thenable; |
| this.resolver = resolver; |
| } |
| |
| AssimilateTask.prototype.run = function() { |
| var h = this.resolver; |
| tryAssimilate(this._then, this.thenable, _resolve, _reject, _notify); |
| |
| function _resolve(x) { h.resolve(x); } |
| function _reject(x) { h.reject(x); } |
| function _notify(x) { h.notify(x); } |
| }; |
| |
| function tryAssimilate(then, thenable, resolve, reject, notify) { |
| try { |
| then.call(thenable, resolve, reject, notify); |
| } catch (e) { |
| reject(e); |
| } |
| } |
| |
| /** |
| * Fold a handler value with z |
| * @constructor |
| */ |
| function Fold(f, z, c, to) { |
| this.f = f; this.z = z; this.c = c; this.to = to; |
| this.resolver = failIfRejected; |
| this.receiver = this; |
| } |
| |
| Fold.prototype.fulfilled = function(x) { |
| this.f.call(this.c, this.z, x, this.to); |
| }; |
| |
| Fold.prototype.rejected = function(x) { |
| this.to.reject(x); |
| }; |
| |
| Fold.prototype.progress = function(x) { |
| this.to.notify(x); |
| }; |
| |
| // Other helpers |
| |
| /** |
| * @param {*} x |
| * @returns {boolean} true iff x is a trusted Promise |
| */ |
| function isPromise(x) { |
| return x instanceof Promise; |
| } |
| |
| /** |
| * Test just enough to rule out primitives, in order to take faster |
| * paths in some code |
| * @param {*} x |
| * @returns {boolean} false iff x is guaranteed *not* to be a thenable |
| */ |
| function maybeThenable(x) { |
| return (typeof x === 'object' || typeof x === 'function') && x !== null; |
| } |
| |
| function runContinuation1(f, h, receiver, next) { |
| if(typeof f !== 'function') { |
| return next.become(h); |
| } |
| |
| Promise.enterContext(h); |
| tryCatchReject(f, h.value, receiver, next); |
| Promise.exitContext(); |
| } |
| |
| function runContinuation3(f, x, h, receiver, next) { |
| if(typeof f !== 'function') { |
| return next.become(h); |
| } |
| |
| Promise.enterContext(h); |
| tryCatchReject3(f, x, h.value, receiver, next); |
| Promise.exitContext(); |
| } |
| |
| /** |
| * @deprecated |
| */ |
| function runNotify(f, x, h, receiver, next) { |
| if(typeof f !== 'function') { |
| return next.notify(x); |
| } |
| |
| Promise.enterContext(h); |
| tryCatchReturn(f, x, receiver, next); |
| Promise.exitContext(); |
| } |
| |
| function tryCatch2(f, a, b) { |
| try { |
| return f(a, b); |
| } catch(e) { |
| return reject(e); |
| } |
| } |
| |
| /** |
| * Return f.call(thisArg, x), or if it throws return a rejected promise for |
| * the thrown exception |
| */ |
| function tryCatchReject(f, x, thisArg, next) { |
| try { |
| next.become(getHandler(f.call(thisArg, x))); |
| } catch(e) { |
| next.become(new Rejected(e)); |
| } |
| } |
| |
| /** |
| * Same as above, but includes the extra argument parameter. |
| */ |
| function tryCatchReject3(f, x, y, thisArg, next) { |
| try { |
| f.call(thisArg, x, y, next); |
| } catch(e) { |
| next.become(new Rejected(e)); |
| } |
| } |
| |
| /** |
| * @deprecated |
| * Return f.call(thisArg, x), or if it throws, *return* the exception |
| */ |
| function tryCatchReturn(f, x, thisArg, next) { |
| try { |
| next.notify(f.call(thisArg, x)); |
| } catch(e) { |
| next.notify(e); |
| } |
| } |
| |
| function inherit(Parent, Child) { |
| Child.prototype = objectCreate(Parent.prototype); |
| Child.prototype.constructor = Child; |
| } |
| |
| function snd(x, y) { |
| return y; |
| } |
| |
| function noop() {} |
| |
| function hasCustomEvent() { |
| if(typeof CustomEvent === 'function') { |
| try { |
| var ev = new CustomEvent('unhandledRejection'); |
| return ev instanceof CustomEvent; |
| } catch (ignoredException) {} |
| } |
| return false; |
| } |
| |
| function hasInternetExplorerCustomEvent() { |
| if(typeof document !== 'undefined' && typeof document.createEvent === 'function') { |
| try { |
| // Try to create one event to make sure it's supported |
| var ev = document.createEvent('CustomEvent'); |
| ev.initCustomEvent('eventType', false, true, {}); |
| return true; |
| } catch (ignoredException) {} |
| } |
| return false; |
| } |
| |
| function initEmitRejection() { |
| /*global process, self, CustomEvent*/ |
| if(typeof process !== 'undefined' && process !== null |
| && typeof process.emit === 'function') { |
| // Returning falsy here means to call the default |
| // onPotentiallyUnhandledRejection API. This is safe even in |
| // browserify since process.emit always returns falsy in browserify: |
| // https://github.com/defunctzombie/node-process/blob/master/browser.js#L40-L46 |
| return function(type, rejection) { |
| return type === 'unhandledRejection' |
| ? process.emit(type, rejection.value, rejection) |
| : process.emit(type, rejection); |
| }; |
| } else if(typeof self !== 'undefined' && hasCustomEvent()) { |
| return (function (self, CustomEvent) { |
| return function (type, rejection) { |
| var ev = new CustomEvent(type, { |
| detail: { |
| reason: rejection.value, |
| key: rejection |
| }, |
| bubbles: false, |
| cancelable: true |
| }); |
| |
| return !self.dispatchEvent(ev); |
| }; |
| }(self, CustomEvent)); |
| } else if(typeof self !== 'undefined' && hasInternetExplorerCustomEvent()) { |
| return (function(self, document) { |
| return function(type, rejection) { |
| var ev = document.createEvent('CustomEvent'); |
| ev.initCustomEvent(type, false, true, { |
| reason: rejection.value, |
| key: rejection |
| }); |
| |
| return !self.dispatchEvent(ev); |
| }; |
| }(self, document)); |
| } |
| |
| return noop; |
| } |
| |
| return Promise; |
| }; |
| }); |
| }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); |
| |
| },{}]},{},[1]) |
| //# sourceMappingURL=Promise.js.map |
| (1) |
| }); |
| ; |