promise comparisons

JavaScript performance comparison

Revision 119 of this test case created by rvmn

Info

This is a comparison of different deferred libraries, performing the most basic tasks of creating a promise, adding a then handler and then resolving the promise. Using async did not give very stable results so went back to sync, at least until jsperf async turns reliable. Update: async added as console run, click button and see your console for the results. And added in test.

Preparation code

<script src="//rawgit.com/bestiejs/benchmark.js/v1.0.0/benchmark.js"></script>
<script src="//rawgithub.com/calvinmetcalf/lie/1.3.0/dist/lie.noConflict.js"></script>
<script>
var SavedPromise=window.Promise;
</script>
<script src="//rawgithub.com/petkaantonov/bluebird/master/js/browser/bluebird.js"></script>
<script>
  window.BluebirdPromise = window.Promise.noConflict();
 window.Promise=SavedPromise;
</script>
<script src="//rsvpjs-builds.s3.amazonaws.com/rsvp-latest.js"></script>
<script src="//rawgithub.com/calvinmetcalf/catiline/gh-pages/dist/catiline.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/q.js/0.9.6/q.min.js">
</script>
<script src="http://s3.amazonaws.com/es6-promises/promise-0.1.0.min.js"></script>
<script>
// Pimp
//# sourceMappingURL=pimp.min.map
!function(n){"use strict";function e(n){function r(n){var e;null!==s&&(n.done||(e=s?n.onFulfilled:n.onRejected,e?t(function(){var t;try{t=e(f),n.resolve(t)}catch(r){n.reject(r)}}):s?n.resolve(f):n.reject(f),n.done=!0))}function o(){for(var n in a)r(a[n])}function i(n){if(null===s){if(n)if(l===n)c(new TypeError("Promise cannot resolve to itself. Sorry brah!"));else if(n.constructor&&"Promise"===n.constructor.name)n.then(i,c);else if("function"==typeof n||"object"==typeof n)try{var e=n.then;"function"==typeof e?u(e.bind(n),i,c):(s=!0,f=n)}catch(t){c(t)}else s=!0,f=n;else s=!0,f=n;o()}}function c(n){null===s&&(s=!1,f=n,o())}function u(n,e,t){var r=!1;try{n(function(n){r||(r=!0,e(n))},function(n){r||(r=!0,t(n))})}catch(o){r||(r=!0,t(o))}}var f,s=null,a=[],l=this;if("function"!=typeof n)return new TypeError("Promise constructor requires a function");try{n(i,c)}catch(p){c(p)}this.then=function(n,t){var o,i=new e(function(e,r){o={promise:i,onFulfilled:"function"==typeof n&&n,onRejected:"function"==typeof t&&t,resolve:e,reject:r,done:!1}});return r(o),a.push(o),i},this.inspect=function(){var n={};return null===s?n.state="pending":s?(n.state="fulfilled",n.value=f):(n.state="rejected",n.reason=f),n}}n.exports?n.exports=e:n.Pimp=e;var t;try{process&&process.nextTick?t=process.nextTick:setImmediate&&(t=setImmediate)}catch(r){t=function(n){window.setTimeout(function(){n()},0)}}}("undefined"==typeof module?window:module),function(n){"use strict";function e(n,e){switch(n){case"Pimp.all":case"Pimp.allFail":case"Pimp.race":if(!(e instanceof Array))throw new SyntaxError(n+" needs to be passed an array");if(!e.length)throw new SyntaxError(n+" needs an array of length >= 1");break;case"Pimp.denodeify":if(!(e instanceof Function))throw new SyntaxError(n+" needs to be passed a function to promisify")}return!0}var t;t="[object Window]"===n.toString()&&"undefined"==typeof require?n.Pimp:require("./pimp"),n.exports?n.exports=t:n.Pimp=t,t.prototype.catch=function(n){return this.then(function(n){return n},n)},t.resolve=function(n){return new t(function(e){e(n)})},t.reject=function(n){return new t(function(e,t){t(n)})},t.cast=function(n){return n instanceof t&&n.then?n:t.resolve(n)},t.all=function(n){return e("Pimp.all",n),new t(function(e,r){var o=0,i=[];for(var c in n)n.hasOwnProperty(c)&&(n[c].then||(n[c]=t.cast(n[c])),n[c].then(function(t){o++,i.push(t),n.length===o&&e(i)},function(n){r(n)}))})},t.allFail=function(n){return e("Pimp.allFail",n),new t(function(e,r){var o=0,i=[];for(var c in n)n.hasOwnProperty(c)&&(n[c].then||(n[c]=t.cast(n[c])),n[c].then(function(n){r(n)},function(t){o++,i.push(t),n.length===o&&e(i)}))})},t.race=function(n){return e("Pimp.race",n),new t(function(e,r){for(var o in n)n.hasOwnProperty(o)&&(n[o].then||(n[o]=t.cast(n[o])),n[o].then(function(n){e(n)},function(n){r(n)}))})},t.deferred=function(){var n={};return n.promise=new t(function(e,t){n.resolve=e,n.reject=t}),n.inspect=n.promise.inspect,n},t.denodeify=function(n){return e("Pimp.denodeify",n),function(){var e=t.deferred(),r=function(n,t){n?e.reject(n):e.resolve(t)};return[].push.call(arguments,r),n.apply(this,arguments),e.promise}}}("undefined"==typeof module?window:module);
</script>
<script>
// when
require=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){(function(define){"use strict";define(function(require){var makePromise=require("./makePromise");var Scheduler=require("./Scheduler");var async=require("./async");return makePromise({scheduler:new Scheduler(async)})})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory(require)})},{"./Scheduler":3,"./async":5,"./makePromise":15}],2:[function(require,module,exports){(function(define){"use strict";define(function(){function Queue(capacityPow2){this.head=this.tail=this.length=0;this.buffer=new Array(1<<capacityPow2)}Queue.prototype.push=function(x){if(this.length===this.buffer.length){this._ensureCapacity(this.length*2)}this.buffer[this.tail]=x;this.tail=this.tail+1&this.buffer.length-1;++this.length;return this.length};Queue.prototype.shift=function(){var x=this.buffer[this.head];this.buffer[this.head]=void 0;this.head=this.head+1&this.buffer.length-1;--this.length;return x};Queue.prototype._ensureCapacity=function(capacity){var head=this.head;var buffer=this.buffer;var newBuffer=new Array(capacity);var i=0;var len;if(head===0){len=this.length;for(;i<len;++i){newBuffer[i]=buffer[i]}}else{capacity=buffer.length;len=this.tail;for(;head<capacity;++i,++head){newBuffer[i]=buffer[head]}for(head=0;head<len;++i,++head){newBuffer[i]=buffer[head]}}this.buffer=newBuffer;this.head=0;this.tail=this.length};return Queue})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory()})},{}],3:[function(require,module,exports){(function(define){"use strict";define(function(require){var Queue=require("./Queue");function Scheduler(async){this._async=async;this._queue=new Queue(15);this._afterQueue=new Queue(5);this._running=false;var self=this;this.drain=function(){self._drain()}}Scheduler.prototype.enqueue=function(task){this._add(this._queue,task)};Scheduler.prototype.afterQueue=function(task){this._add(this._afterQueue,task)};Scheduler.prototype._drain=function(){runQueue(this._queue);this._running=false;runQueue(this._afterQueue)};Scheduler.prototype._add=function(queue,task){queue.push(task);if(!this._running){this._running=true;this._async(this.drain)}};function runQueue(queue){while(queue.length>0){queue.shift().run()}}return Scheduler})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory(require)})},{"./Queue":2}],4:[function(require,module,exports){(function(define){"use strict";define(function(){function TimeoutError(message){Error.call(this);this.message=message;this.name=TimeoutError.name;if(typeof Error.captureStackTrace==="function"){Error.captureStackTrace(this,TimeoutError)}}TimeoutError.prototype=Object.create(Error.prototype);TimeoutError.prototype.constructor=TimeoutError;return TimeoutError})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory()})},{}],5:[function(require,module,exports){(function(process){(function(define){"use strict";define(function(require){var nextTick,MutationObs;if(typeof process!=="undefined"&&process!==null&&typeof process.nextTick==="function"){nextTick=function(f){process.nextTick(f)}}else if(MutationObs=typeof MutationObserver==="function"&&MutationObserver||typeof WebKitMutationObserver==="function"&&WebKitMutationObserver){nextTick=function(document,MutationObserver){var scheduled;var el=document.createElement("div");var o=new MutationObserver(run);o.observe(el,{attributes:true});function run(){var f=scheduled;scheduled=void 0;f()}return function(f){scheduled=f;el.setAttribute("class","x")}}(document,MutationObs)}else{nextTick=function(cjsRequire){try{return cjsRequire("vertx").runOnLoop||cjsRequire("vertx").runOnContext}catch(ignore){}var capturedSetTimeout=setTimeout;return function(t){capturedSetTimeout(t,0)}}(require)}return nextTick})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory(require)})}).call(this,require("lppjwH"))},{lppjwH:19}],6:[function(require,module,exports){(function(define){"use strict";define(function(){return function array(Promise){var arrayReduce=Array.prototype.reduce;var arrayReduceRight=Array.prototype.reduceRight;var toPromise=Promise.resolve;var all=Promise.all;Promise.any=any;Promise.some=some;Promise.settle=settle;Promise.map=map;Promise.filter=filter;Promise.reduce=reduce;Promise.reduceRight=reduceRight;Promise.prototype.spread=function(onFulfilled){return this.then(all).then(function(array){return onFulfilled.apply(void 0,array)})};return Promise;function any(promises){return new Promise(function(resolve,reject){var errors=[];var pending=initRace(promises,resolve,handleReject);if(pending===0){reject(new RangeError("any() input must not be empty"))}function handleReject(e){errors.push(e);if(--pending===0){reject(errors)}}})}function some(promises,n){return new Promise(function(resolve,reject,notify){var results=[];var errors=[];var nReject;var nFulfill=initRace(promises,handleResolve,handleReject,notify);n=Math.max(n,0);nReject=nFulfill-n+1;nFulfill=Math.min(n,nFulfill);if(n>nFulfill){reject(new RangeError("some() input must contain at least "+n+" element(s), but had "+nFulfill))}else if(nFulfill===0){resolve(results)}function handleResolve(x){if(nFulfill>0){--nFulfill;results.push(x);if(nFulfill===0){resolve(results)}}}function handleReject(e){if(nReject>0){--nReject;errors.push(e);if(nReject===0){reject(errors)}}}})}function initRace(promises,resolve,reject,notify){return arrayReduce.call(promises,function(pending,p){toPromise(p).then(resolve,reject,notify);return pending+1},0)}function map(promises,f){if(typeof promises!=="object"){return toPromise([])}return all(mapArray(function(x,i){return toPromise(x).fold(mapWithIndex,i)},promises));function mapWithIndex(k,x){return f(x,k)}}function filter(promises,predicate){return all(promises).then(function(values){return all(mapArray(predicate,values)).then(function(results){var len=results.length;var filtered=new Array(len);for(var i=0,j=0,x;i<len;++i){x=results[i];if(x===void 0&&!(i in results)){continue}if(results[i]){filtered[j++]=values[i]}}filtered.length=j;return filtered})})}function settle(promises){return all(mapArray(function(p){p=toPromise(p);return p.then(inspect,inspect);function inspect(){return p.inspect()}},promises))}function reduce(promises,f){var reducer=makeReducer(f);return arguments.length>2?arrayReduce.call(promises,reducer,arguments[2]):arrayReduce.call(promises,reducer)}function reduceRight(promises,f){var reducer=makeReducer(f);return arguments.length>2?arrayReduceRight.call(promises,reducer,arguments[2]):arrayReduceRight.call(promises,reducer)}function makeReducer(f){return function reducer(result,x,i){return toPromise(result).then(function(r){return toPromise(x).then(function(x){return f(r,x,i)})})}}function mapArray(f,a){var l=a.length;var b=new Array(l);for(var i=0,x;i<l;++i){x=a[i];if(x===void 0&&!(i in a)){continue}b[i]=f(a[i],i)}return b}}})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory()})},{}],7:[function(require,module,exports){(function(define){"use strict";define(function(){return function flow(Promise){var reject=Promise.reject;var origCatch=Promise.prototype["catch"];Promise.prototype.done=function(onResult,onError){this._handler.visit(this._handler.receiver,onResult,onError)};Promise.prototype["catch"]=Promise.prototype.otherwise=function(onRejected){if(arguments.length===1){return origCatch.call(this,onRejected)}else{if(typeof onRejected!=="function"){return this.ensure(rejectInvalidPredicate)}return origCatch.call(this,createCatchFilter(arguments[1],onRejected))}};function createCatchFilter(handler,predicate){return function(e){return evaluatePredicate(e,predicate)?handler.call(this,e):reject(e)}}Promise.prototype["finally"]=Promise.prototype.ensure=function(handler){if(typeof handler!=="function"){return this}handler=isolate(handler,this);return this.then(handler,handler)};Promise.prototype["else"]=Promise.prototype.orElse=function(defaultValue){return this.then(void 0,function(){return defaultValue})};Promise.prototype["yield"]=function(value){return this.then(function(){return value})};Promise.prototype.tap=function(onFulfilledSideEffect){return this.then(onFulfilledSideEffect)["yield"](this)};return Promise};function rejectInvalidPredicate(){throw new TypeError("catch predicate must be a function")}function evaluatePredicate(e,predicate){return isError(predicate)?e instanceof predicate:predicate(e)}function isError(predicate){return predicate===Error||predicate!=null&&predicate.prototype instanceof Error}function isolate(f,x){return function(){f.call(this);return x}}})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory()})},{}],8:[function(require,module,exports){(function(define){"use strict";define(function(){return function fold(Promise){Promise.prototype.fold=function(f,z){var promise=this._beget();this._handler.fold(function(z,x,to){Promise._handler(z).fold(function(x,z,to){to.resolve(f.call(this,z,x))},x,this,to)},z,promise._handler.receiver,promise._handler);return promise};return Promise}})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory()})},{}],9:[function(require,module,exports){(function(define){"use strict";define(function(){return function inspection(Promise){Promise.prototype.inspect=function(){return inspect(Promise._handler(this))};function inspect(handler){var state=handler.state();if(state===0){return{state:"pending"}}if(state>0){return{state:"fulfilled",value:handler.value}}return{state:"rejected",reason:handler.value}}return Promise}})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory()})},{}],10:[function(require,module,exports){(function(define){"use strict";define(function(){return function generate(Promise){var resolve=Promise.resolve;Promise.iterate=iterate;Promise.unfold=unfold;return Promise;function iterate(f,condition,handler,x){return unfold(function(x){return[x,f(x)]},condition,handler,x)}function unfold(unspool,condition,handler,x){return resolve(x).then(function(seed){return resolve(condition(seed)).then(function(done){return done?seed:resolve(unspool(seed)).spread(next)})});function next(item,newSeed){return resolve(handler(item)).then(function(){return unfold(unspool,condition,handler,newSeed)})}}}})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory()})},{}],11:[function(require,module,exports){(function(define){"use strict";define(function(){return function progress(Promise){Promise.prototype.progress=function(onProgress){return this.then(void 0,void 0,onProgress)};return Promise}})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory()})},{}],12:[function(require,module,exports){(function(define){"use strict";define(function(require){var timer=require("../timer");var TimeoutError=require("../TimeoutError");function setTimeout(f,ms,x,y){return timer.set(function(){f(x,y,ms)},ms)}return function timed(Promise){Promise.prototype.delay=function(ms){var p=this._beget();this._handler.fold(handleDelay,ms,void 0,p._handler);return p};function handleDelay(ms,x,h){setTimeout(resolveDelay,ms,x,h)}function resolveDelay(x,h){h.resolve(x)}Promise.prototype.timeout=function(ms,reason){var p=this._beget();var h=p._handler;var t=setTimeout(onTimeout,ms,reason,p._handler);this._handler.visit(h,function onFulfill(x){timer.clear(t);this.resolve(x)},function onReject(x){timer.clear(t);this.reject(x)},h.notify);return p};function onTimeout(reason,h,ms){var e=typeof reason==="undefined"?new TimeoutError("timed out after "+ms+"ms"):reason;h.reject(e)}return Promise}})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory(require)})},{"../TimeoutError":4,"../timer":16}],13:[function(require,module,exports){(function(define){"use strict";define(function(require){var timer=require("../timer");return function unhandledRejection(Promise){var logError=noop;var logInfo=noop;if(typeof console!=="undefined"){logError=typeof console.error!=="undefined"?function(e){console.error(e)}:function(e){console.log(e)};logInfo=typeof console.info!=="undefined"?function(e){console.info(e)}:function(e){console.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=false;function report(r){if(!r.handled){reported.push(r);logError("Potentially unhandled rejection ["+r.id+"] "+formatError(r.value))}}function unreport(r){var i=reported.indexOf(r);if(i>=0){reported.splice(i,1);logInfo("Handled previous rejection ["+r.id+"] "+formatObject(r.value))}}function enqueue(f,x){tasks.push(f,x);if(!running){running=true;running=timer.set(flush,0)}}function flush(){running=false;while(tasks.length>0){tasks.shift()(tasks.shift())}}return Promise};function formatError(e){var s=typeof e==="object"&&e.stack?e.stack:formatObject(e);return e instanceof Error?s:s+" (WARNING: non-Error used)"}function formatObject(o){var s=String(o);if(s==="[object Object]"&&typeof JSON!=="undefined"){s=tryStringify(o,s)}return s}function tryStringify(e,defaultValue){try{return JSON.stringify(e)}catch(e){return defaultValue}}function throwit(e){throw e}function noop(){}})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory(require)})},{"../timer":16}],14:[function(require,module,exports){(function(define){"use strict";define(function(){return function addWith(Promise){Promise.prototype["with"]=Promise.prototype.withThis=function(receiver){var p=this._beget();var child=p._handler;child.receiver=receiver;this._handler.chain(child,receiver);return p};return Promise}})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory()})},{}],15:[function(require,module,exports){(function(define){"use strict";define(function(){return function makePromise(environment){var tasks=environment.scheduler;var objectCreate=Object.create||function(proto){function Child(){}Child.prototype=proto;return new Child};function Promise(resolver,handler){this._handler=resolver===Handler?handler:init(resolver)}function init(resolver){var handler=new Pending;try{resolver(promiseResolve,promiseReject,promiseNotify)}catch(e){promiseReject(e)}return handler;function promiseResolve(x){handler.resolve(x)}function promiseReject(reason){handler.reject(reason)}function promiseNotify(x){handler.notify(x)}}Promise.resolve=resolve;Promise.reject=reject;Promise.never=never;Promise._defer=defer;Promise._handler=getHandler;function resolve(x){return isPromise(x)?x:new Promise(Handler,new Async(getHandler(x)))}function reject(x){return new Promise(Handler,new Async(new Rejected(x)))}function never(){return foreverPendingPromise}function defer(){return new Promise(Handler,new Pending)}Promise.prototype.then=function(onFulfilled,onRejected){var parent=this._handler;if(typeof onFulfilled!=="function"&&parent.join().state()>0){return new Promise(Handler,parent)}var p=this._beget();var child=p._handler;parent.chain(child,parent.receiver,onFulfilled,onRejected,arguments.length>2?arguments[2]:void 0);return p};Promise.prototype["catch"]=function(onRejected){return this.then(void 0,onRejected)};Promise.prototype._beget=function(){var parent=this._handler;var child=new Pending(parent.receiver,parent.join().context);return new this.constructor(Handler,child)};Promise.all=all;Promise.race=race;function all(promises){var resolver=new Pending;var pending=promises.length>>>0;var results=new Array(pending);var i,h,x,s;for(i=0;i<promises.length;++i){x=promises[i];if(x===void 0&&!(i in promises)){--pending;continue}if(maybeThenable(x)){h=isPromise(x)?x._handler.join():getHandlerUntrusted(x);s=h.state();if(s===0){h.fold(settleAt,i,results,resolver)}else if(s>0){results[i]=h.value;--pending}else{resolver.become(h);break}}else{results[i]=x;--pending}}if(pending===0){resolver.become(new Fulfilled(results))}return new Promise(Handler,resolver);function settleAt(i,x,resolver){this[i]=x;if(--pending===0){resolver.become(new Fulfilled(this))}}}function race(promises){if(Object(promises)===promises&&promises.length===0){return never()}var h=new Pending;var i,x;for(i=0;i<promises.length;++i){x=promises[i];if(x!==void 0&&i in promises){getHandler(x).visit(h,h.resolve,h.reject)}}return new Promise(Handler,h)}function getHandler(x){if(isPromise(x)){return x._handler.join()}return maybeThenable(x)?getHandlerUntrusted(x):new Fulfilled(x)}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)}}function Handler(){}Handler.prototype.when=Handler.prototype.become=Handler.prototype.notify=Handler.prototype.fail=Handler.prototype._unreport=Handler.prototype._report=noop;Handler.prototype._state=0;Handler.prototype.state=function(){return this._state};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.visit(to,function(x){f.call(c,z,x,this)},to.reject,to.notify)};function FailIfRejected(){}inherit(Handler,FailIfRejected);FailIfRejected.prototype.become=function(h){h.fail()};var failIfRejected=new FailIfRejected;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.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)}}};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()};function Delegating(handler){this.handler=handler}inherit(Handler,Delegating);Delegating.prototype._report=function(context){this.join()._report(context)};Delegating.prototype._unreport=function(){this.join()._unreport()};function Async(handler){Delegating.call(this,handler)}inherit(Delegating,Async);Async.prototype.when=function(continuation){tasks.enqueue(new ContinuationTask(continuation,this))};function Thenable(then,thenable){Pending.call(this);tasks.enqueue(new AssimilateTask(then,thenable,this))}inherit(Pending,Thenable);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;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){this._unreport();to.become(this)};Rejected.prototype.when=function(cont){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(){this.handled=true;tasks.afterQueue(new UnreportTask(this))};Rejected.prototype.fail=function(context){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=true;Promise.onPotentiallyUnhandledRejection(this.rejection,this.context)}};function UnreportTask(rejection){this.rejection=rejection}UnreportTask.prototype.run=function(){if(this.rejection.reported){Promise.onPotentiallyUnhandledRejectionHandled(this.rejection)}};Promise.createContext=Promise.enterContext=Promise.exitContext=Promise.onPotentiallyUnhandledRejection=Promise.onPotentiallyUnhandledRejectionHandled=Promise.onFatalRejection=noop;var foreverPendingHandler=new Handler;var foreverPendingPromise=new Promise(Handler,foreverPendingHandler);function cycle(){return new Rejected(new TypeError("Promise cycle"))}function ContinuationTask(continuation,handler){this.continuation=continuation;this.handler=handler}ContinuationTask.prototype.run=function(){this.handler.join().when(this.continuation)};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)}};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)}}function isPromise(x){return x instanceof Promise}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()}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 tryCatchReject(f,x,thisArg,next){try{next.become(getHandler(f.call(thisArg,x)))}catch(e){next.become(new Rejected(e))}}function tryCatchReject3(f,x,y,thisArg,next){try{f.call(thisArg,x,y,next)}catch(e){next.become(new Rejected(e))}}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 noop(){}return Promise}})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory()})},{}],16:[function(require,module,exports){(function(define){"use strict";define(function(require){var cjsRequire,vertx,setTimer,clearTimer;cjsRequire=require;try{vertx=cjsRequire("vertx");setTimer=function(f,ms){return vertx.setTimer(ms,f)};clearTimer=vertx.cancelTimer}catch(e){setTimer=function(f,ms){return setTimeout(f,ms)};clearTimer=function(t){return clearTimeout(t)}}return{set:setTimer,clear:clearTimer}})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory(require)})},{}],Ug1Vj9:[function(require,module,exports){(function(define){"use strict";define(function(require){var timed=require("./lib/decorators/timed");var array=require("./lib/decorators/array");var flow=require("./lib/decorators/flow");var fold=require("./lib/decorators/fold");var inspect=require("./lib/decorators/inspect");var generate=require("./lib/decorators/iterate");var progress=require("./lib/decorators/progress");var withThis=require("./lib/decorators/with");var unhandledRejection=require("./lib/decorators/unhandledRejection");var TimeoutError=require("./lib/TimeoutError");var Promise=[array,flow,fold,generate,progress,inspect,withThis,timed,unhandledRejection].reduce(function(Promise,feature){return feature(Promise)},require("./lib/Promise"));var slice=Array.prototype.slice;when.promise=promise;when.resolve=Promise.resolve;when.reject=Promise.reject;when.lift=lift;when["try"]=attempt;when.attempt=attempt;when.iterate=Promise.iterate;when.unfold=Promise.unfold;when.join=join;when.all=all;when.settle=settle;when.any=lift(Promise.any);when.some=lift(Promise.some);when.race=lift(Promise.race);when.map=map;when.filter=filter;when.reduce=reduce;when.reduceRight=reduceRight;when.isPromiseLike=isPromiseLike;when.Promise=Promise;when.defer=defer;when.TimeoutError=TimeoutError;function when(x,onFulfilled,onRejected){var p=Promise.resolve(x);if(arguments.length<2){return p}return arguments.length>3?p.then(onFulfilled,onRejected,arguments[3]):p.then(onFulfilled,onRejected)}function promise(resolver){return new Promise(resolver)}function lift(f){return function(){return _apply(f,this,slice.call(arguments))}}function attempt(f){return _apply(f,this,slice.call(arguments,1))}function _apply(f,thisArg,args){return Promise.all(args).then(function(args){return f.apply(thisArg,args)})}function defer(){return new Deferred}function Deferred(){var p=Promise._defer();function resolve(x){p._handler.resolve(x)}function reject(x){p._handler.reject(x)}function notify(x){p._handler.notify(x)}this.promise=p;this.resolve=resolve;this.reject=reject;this.notify=notify;this.resolver={resolve:resolve,reject:reject,notify:notify}}function isPromiseLike(x){return x&&typeof x.then==="function"}function join(){return Promise.all(arguments)}function all(promises){return when(promises,Promise.all)}function settle(promises){return when(promises,Promise.settle)}function map(promises,mapFunc){return when(promises,function(promises){return Promise.map(promises,mapFunc)})}function filter(promises,predicate){return when(promises,function(promises){return Promise.filter(promises,predicate)})}function reduce(promises,f){var args=slice.call(arguments,1);return when(promises,function(array){args.unshift(array);return Promise.reduce.apply(Promise,args)})}function reduceRight(promises,f){var args=slice.call(arguments,1);return when(promises,function(array){args.unshift(array);return Promise.reduceRight.apply(Promise,args)})}return when})})(typeof define==="function"&&define.amd?define:function(factory){module.exports=factory(require)})},{"./lib/Promise":1,"./lib/TimeoutError":4,"./lib/decorators/array":6,"./lib/decorators/flow":7,"./lib/decorators/fold":8,"./lib/decorators/inspect":9,"./lib/decorators/iterate":10,"./lib/decorators/progress":11,"./lib/decorators/timed":12,"./lib/decorators/unhandledRejection":13,"./lib/decorators/with":14}],when:[function(require,module,exports){module.exports=require("Ug1Vj9")},{}],19:[function(require,module,exports){var process=module.exports={};process.nextTick=function(){var canSetImmediate=typeof window!=="undefined"&&window.setImmediate;var canPost=typeof window!=="undefined"&&window.postMessage&&window.addEventListener;if(canSetImmediate){return function(f){return window.setImmediate(f)}}if(canPost){var queue=[];window.addEventListener("message",function(ev){var source=ev.source;if((source===window||source===null)&&ev.data==="process-tick"){ev.stopPropagation();if(queue.length>0){var fn=queue.shift();fn()}}},true);return function nextTick(fn){queue.push(fn);window.postMessage("process-tick","*")}}return function nextTick(fn){setTimeout(fn,0)}}();process.title="browser";process.browser=true;process.env={};process.argv=[];function noop(){}process.on=noop;process.addListener=noop;process.once=noop;process.off=noop;process.removeListener=noop;process.removeAllListeners=noop;process.emit=noop;process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")}},{}]},{},[]);
</script>
<script>when=require('when')</script>
<script>
// Kew
window.K = (function(){
/** @typedef {function(?, ?)} */
var OnSuccessCallbackType;
/** @typedef {function(!Error, ?)} */
var OnFailCallbackType;
function Promise(onSuccess, onFail) {
  this.promise = this
  this._isPromise = true
  this._successFn = onSuccess
  this._failFn = onFail
  this._scope = this
  this._boundArgs = null
  this._hasContext = false
  this._nextContext = undefined
  this._currentContext = undefined
}

/**
 * Keep track of the number of promises that are rejected along side
 * the number of rejected promises we call _failFn on so we can look
 * for leaked rejections.
 */

function PromiseStats() {
  this.errorsEmitted = 0
  this.errorsHandled = 0
}

var stats = new PromiseStats()

Promise.prototype._handleError = function () {
  if (!this._errorHandled) {
    stats.errorsHandled++
    this._errorHandled = true
  }
}

/**
 * Specify that the current promise should have a specified context
 * @param  {*} context context
 * @private
 */

Promise.prototype._useContext = function (context) {
  this._nextContext = this._currentContext = context
  this._hasContext = true
  return this
}

Promise.prototype.clearContext = function () {
  this._hasContext = false
  this._nextContext = undefined
  return this
}

/**
 * Set the context for all promise handlers to follow
 *
 * NOTE(dpup): This should be considered deprecated.  It does not do what most
 * people would expect.  The context will be passed as a second argument to all
 * subsequent callbacks.
 *
 * @param {*} context An arbitrary context
 */

Promise.prototype.setContext = function (context) {
  this._nextContext = context
  this._hasContext = true
  return this
}

/**
 * Get the context for a promise
 * @return {*} the context set by setContext
 */

Promise.prototype.getContext = function () {
  return this._nextContext
}

/**
 * Resolve this promise with a specified value
 *
 * @param {*=} data
 */

Promise.prototype.resolve = function (data) {
  if (this._error || this._hasData) throw new Error("Unable to resolve or reject the same promise twice")

  var i
  if (data && isPromise(data)) {
    this._child = data
    if (this._promises) {
      for (i = 0; i < this._promises.length; i += 1) {
        data._chainPromise(this._promises[i])
      }
      delete this._promises
    }

    if (this._onComplete) {
      for (i = 0; i < this._onComplete.length; i+= 1) {
        data.fin(this._onComplete[i])
      }
      delete this._onComplete
    }
  } else if (data && isPromiseLike(data)) {
    data.then(
      function(data) { this.resolve(data) }.bind(this),
      function(err) { this.reject(err) }.bind(this)
    )
  } else {
    this._hasData = true
    this._data = data

    if (this._onComplete) {
      for (i = 0; i < this._onComplete.length; i++) {
        this._onComplete[i]()
      }
    }

    if (this._promises) {
      for (i = 0; i < this._promises.length; i += 1) {
        this._promises[i]._withInput(data)
      }
      delete this._promises
    }
  }
}

/**
 * Reject this promise with an error
 *
 * @param {!Error} e
 */

Promise.prototype.reject = function (e) {
  if (this._error || this._hasData) throw new Error("Unable to resolve or reject the same promise twice")

  var i
  this._error = e
  stats.errorsEmitted++

  if (this._ended) {
    this._handleError()
    process.nextTick(function onPromiseThrow() {
      throw e
    })
  }

  if (this._onComplete) {
    for (i = 0; i < this._onComplete.length; i++) {
      this._onComplete[i]()
    }
  }

  if (this._promises) {
    this._handleError()
    for (i = 0; i < this._promises.length; i += 1) {
      this._promises[i]._withError(e)
    }
    delete this._promises
  }
}

/**
 * Provide a callback to be called whenever this promise successfully
 * resolves. Allows for an optional second callback to handle the failure
 * case.
 *
 * @param {?function(this:void, T, ?): RESULT|undefined} onSuccess
 * @param {?function(this:void, !Error, ?): RESULT=} onFail
 * @return {!Promise.<RESULT>} returns a new promise with the output of the onSuccess or
 *     onFail handler
 * @template RESULT
 */

Promise.prototype.then = function (onSuccess, onFail) {
  var promise = new Promise(onSuccess, onFail)
  if (this._nextContext) promise._useContext(this._nextContext)

  if (this._child) this._child._chainPromise(promise)
  else this._chainPromise(promise)

  return promise
}

/**
 * Provide a callback to be called whenever this promise successfully
 * resolves. The callback will be executed in the context of the provided scope.
 *
 * @param {function(this:SCOPE, T, ?): RESULT} onSuccess
 * @param {SCOPE} scope Object whose context callback will be executed in.
 * @param {...*} var_args Additional arguments to be passed to the promise callback.
 * @return {!Promise.<RESULT>} returns a new promise with the output of the onSuccess
 * @template SCOPE, RESULT
 */

Promise.prototype.thenBound = function (onSuccess, scope, var_args) {
  var promise = new Promise(onSuccess)
  if (this._nextContext) promise._useContext(this._nextContext)

  promise._scope = scope
  if (arguments.length > 2) {
    promise._boundArgs = Array.prototype.slice.call(arguments, 2)
  }

  // Chaining must happen after setting args and scope since it may fire callback.
  if (this._child) this._child._chainPromise(promise)
  else this._chainPromise(promise)

  return promise
}

/**
 * Provide a callback to be called whenever this promise is rejected
 *
 * @param {function(this:void, !Error, ?)} onFail
 * @return {!Promise.<T>} returns a new promise with the output of the onFail handler
 */

Promise.prototype.fail = function (onFail) {
  return this.then(null, onFail)
}

/**
 * Provide a callback to be called whenever this promise is rejected.
 * The callback will be executed in the context of the provided scope.
 *
 * @param {function(this:SCOPE, Error, ?)} onFail
 * @param {SCOPE} scope Object whose context callback will be executed in.
 * @param {...?} var_args
 * @return {!Promise.<T>} returns a new promise with the output of the onSuccess
 * @template SCOPE
 */

Promise.prototype.failBound = function (onFail, scope, var_args) {
  var promise = new Promise(null, onFail)
  if (this._nextContext) promise._useContext(this._nextContext)

  promise._scope = scope
  if (arguments.length > 2) {
    promise._boundArgs = Array.prototype.slice.call(arguments, 2)
  }

  // Chaining must happen after setting args and scope since it may fire callback.
  if (this._child) this._child._chainPromise(promise)
  else this._chainPromise(promise)

  return promise
}

/**
 * Provide a callback to be called whenever this promise is either resolved
 * or rejected.
 *
 * @param {function()} onComplete
 * @return {!Promise.<T>} returns the current promise
 */

Promise.prototype.fin = function (onComplete) {
  if (this._hasData || this._error) {
    onComplete()
    return this
  }

  if (this._child) {
    this._child.fin(onComplete)
  } else {
    if (!this._onComplete) this._onComplete = [onComplete]
    else this._onComplete.push(onComplete)
  }

  return this
}

/**
 * Mark this promise as "ended". If the promise is rejected, this will throw an
 * error in whatever scope it happens to be in
 *
 * @return {!Promise.<T>} returns the current promise
 * @deprecated Prefer done(), because it's consistent with Q.
 */

Promise.prototype.end = function () {
  this._end()
  return this
}


/**
 * Mark this promise as "ended".
 * @private
 */

Promise.prototype._end = function () {
  if (this._error) {
    this._handleError()
    throw this._error
  }
  this._ended = true
  return this
}

/**
 * Close the promise. Any errors after this completes will be thrown to the global handler.
 *
 * @param {?function(this:void, T, ?)=} onSuccess a function to handle successful
 *     resolution of this promise
 * @param {?function(this:void, !Error, ?)=} onFailure a function to handle failed
 *     resolution of this promise
 * @return {void}
 */

Promise.prototype.done = function (onSuccess, onFailure) {
  var self = this
  if (onSuccess || onFailure) {
    self = self.then(onSuccess, onFailure)
  }
  self._end()
}

/**
 * Return a new promise that behaves the same as the current promise except
 * that it will be rejected if the current promise does not get fulfilled
 * after a certain amount of time.
 *
 * @param {number} timeoutMs The timeout threshold in msec
 * @param {string=} timeoutMsg error message
 * @return {!Promise.<T>} a new promise with timeout
 */

 Promise.prototype.timeout = function (timeoutMs, timeoutMsg) {
  var deferred = new Promise()
  var isTimeout = false

  var timeout = setTimeout(function() {
    deferred.reject(new Error(timeoutMsg || 'Promise timeout after ' + timeoutMs + ' ms.'))
    isTimeout = true
  }, timeoutMs)

  this.then(function (data) {
    if (!isTimeout) {
      clearTimeout(timeout)
      deferred.resolve(data)
    }
  },
  function (err) {
    if (!isTimeout) {
      clearTimeout(timeout)
      deferred.reject(err)
    }
  })

  return deferred.promise
}

/**
 * Attempt to resolve this promise with the specified input
 *
 * @param {*} data the input
 */

Promise.prototype._withInput = function (data) {
  if (this._successFn) {
    try {
      this.resolve(this._call(this._successFn, [data, this._currentContext]))
    } catch (e) {
      this.reject(e)
    }
  } else this.resolve(data)

  // context is no longer needed
  delete this._currentContext
}

/**
 * Attempt to reject this promise with the specified error
 *
 * @param {!Error} e
 * @private
 */

Promise.prototype._withError = function (e) {
  if (this._failFn) {
    try {
      this.resolve(this._call(this._failFn, [e, this._currentContext]))
    } catch (thrown) {
      this.reject(thrown)
    }
  } else this.reject(e)

  // context is no longer needed
  delete this._currentContext
}

/**
 * Calls a function in the correct scope, and includes bound arguments.
 * @param {Function} fn
 * @param {Array} args
 * @return {*}
 * @private
 */

Promise.prototype._call = function (fn, args) {
  if (this._boundArgs) {
    args = this._boundArgs.concat(args)
  }
  return fn.apply(this._scope, args)
}

/**
 * Chain a promise to the current promise
 *
 * @param {!Promise} promise the promise to chain
 * @private
 */

Promise.prototype._chainPromise = function (promise) {
  var i
  if (this._hasContext) promise._useContext(this._nextContext)

  if (this._child) {
    this._child._chainPromise(promise)
  } else if (this._hasData) {
    promise._withInput(this._data)
  } else if (this._error) {
    // We can't rely on _withError() because it's called on the chained promises
    // and we need to use the source's _errorHandled state
    this._handleError()
    promise._withError(this._error)
  } else if (!this._promises) {
    this._promises = [promise]
  } else {
    this._promises.push(promise)
  }
}

/**
 * Utility function used for creating a node-style resolver
 * for deferreds
 *
 * @param {!Promise} deferred a promise that looks like a deferred
 * @param {Error=} err an optional error
 * @param {*=} data optional data
 */

function resolver(deferred, err, data) {
  if (err) deferred.reject(err)
  else deferred.resolve(data)
}

/**
 * Creates a node-style resolver for a deferred by wrapping
 * resolver()
 *
 * @return {function(?Error, *)} node-style callback
 */

Promise.prototype.makeNodeResolver = function () {
  return resolver.bind(null, this)
}

/**
 * Return true iff the given object is a promise of this library.
 *
 * Because kew's API is slightly different than other promise libraries,
 * it's important that we have a test for its promise type. If you want
 * to test for a more general A+ promise, you should do a cap test for
 * the features you want.
 *
 * @param {*} obj The object to test
 * @return {boolean} Whether the object is a promise
 */

function isPromise(obj) {
  return !!obj._isPromise
}

/**
 * Return true iff the given object is a promise-like object, e.g. appears to
 * implement Promises/A+ specification
 *
 * @param {*} obj The object to test
 * @return {boolean} Whether the object is a promise-like object
 */

function isPromiseLike(obj) {
  return typeof obj === 'object' && typeof obj.then === 'function'
}

/**
 * Static function which creates and resolves a promise immediately
 *
 * @param {T} data data to resolve the promise with
 * @return {!Promise.<T>}
 * @template T
 */

function resolve(data) {
  var promise = new Promise()
  promise.resolve(data)
  return promise
}

/**
 * Static function which creates and rejects a promise immediately
 *
 * @param {!Error} e error to reject the promise with
 * @return {!Promise}
 */

function reject(e) {
  var promise = new Promise()
  promise.reject(e)
  return promise
}

/**
 * Replace an element in an array with a new value. Used by .all() to
 * call from .then()
 *
 * @param {!Array} arr
 * @param {number} idx
 * @param {*} val
 * @return {*} the val that's being injected into the array
 */

function replaceEl(arr, idx, val) {
  arr[idx] = val
  return val
}

/**
 * Replace an element in an array as it is resolved with its value.
 * Used by .allSettled().
 *
 * @param {!Array} arr
 * @param {number} idx
 * @param {*} value The value from a resolved promise.
 * @return {*} the data that's being passed in
 */

function replaceElFulfilled(arr, idx, value) {
  arr[idx] = {
    state: 'fulfilled',
    value: value
  }
  return value
}

/**
 * Replace an element in an array as it is rejected with the reason.
 * Used by .allSettled().
 *
 * @param {!Array} arr
 * @param {number} idx
 * @param {*} reason The reason why the original promise is rejected
 * @return {*} the data that's being passed in
 */

function replaceElRejected(arr, idx, reason) {
  arr[idx] = {
    state: 'rejected',
    reason: reason
  }
  return reason
}

/**
 * Takes in an array of promises or literals and returns a promise which returns
 * an array of values when all have resolved. If any fail, the promise fails.
 *
 * @param {!Array.<!Promise>} promises
 * @return {!Promise.<!Array>}
 */

function all(promises) {
  if (arguments.length != 1 || !Array.isArray(promises)) {
    promises = Array.prototype.slice.call(arguments, 0)
  }
  if (!promises.length) return resolve([])

  var outputs = []
  var finished = false
  var promise = new Promise()
  var counter = promises.length

  for (var i = 0; i < promises.length; i += 1) {
    if (!promises[i] || !isPromiseLike(promises[i])) {
      outputs[i] = promises[i]
      counter -= 1
    } else {
      promises[i].then(replaceEl.bind(null, outputs, i))
      .then(function decrementAllCounter() {
        counter--
        if (!finished && counter === 0) {
          finished = true
          promise.resolve(outputs)
        }
      }, function onAllError(e) {
        if (!finished) {
          finished = true
          promise.reject(e)
        }
      })
    }
  }

  if (counter === 0 && !finished) {
    finished = true
    promise.resolve(outputs)
  }

  return promise
}

/**
 * Takes in an array of promises or values and returns a promise that is
 * fulfilled with an array of state objects when all have resolved or
 * rejected. If a promise is resolved, its corresponding state object is
 * {state: 'fulfilled', value: Object}; whereas if a promise is rejected, its
 * corresponding state object is {state: 'rejected', reason: Object}.
 *
 * @param {!Array} promises or values
 * @return {!Promise.<!Array>} Promise fulfilled with state objects for each input
 */

function allSettled(promises) {
  if (!Array.isArray(promises)) {
    throw Error('The input to "allSettled()" should be an array of Promise or values')
  }
  if (!promises.length) return resolve([])

  var outputs = []
  var promise = new Promise()
  var counter = promises.length

  for (var i = 0; i < promises.length; i += 1) {
    if (!promises[i] || !isPromiseLike(promises[i])) {
      replaceElFulfilled(outputs, i, promises[i])
      if ((--counter) === 0) promise.resolve(outputs)
    } else {
      promises[i]
        .then(replaceElFulfilled.bind(null, outputs, i), replaceElRejected.bind(null, outputs, i))
        .then(function () {
          if ((--counter) === 0) promise.resolve(outputs)
        })
    }
  }

  return promise
}

/**
 * Create a new Promise which looks like a deferred
 *
 * @return {!Promise}
 */

function defer() {
  return new Promise()
}

/**
 * Return a promise which will wait a specified number of ms to resolve
 *
 * @param {*} delayMsOrVal A delay (in ms) if this takes one argument, or ther
 *     return value if it takes two.
 * @param {number=} opt_delayMs
 * @return {!Promise}
 */

function delay(delayMsOrVal, opt_delayMs) {
  var returnVal = undefined
  var delayMs = delayMsOrVal
  if (typeof opt_delayMs != 'undefined') {
    delayMs = opt_delayMs
    returnVal = delayMsOrVal
  }

  if (typeof delayMs != 'number') {
    throw new Error('Bad delay value ' + delayMs)
  }

  var defer = new Promise()
  setTimeout(function onDelay() {
    defer.resolve(returnVal)
  }, delayMs)
  return defer
}

/**
 * Returns a promise that has the same result as `this`, but fulfilled
 * after at least ms milliseconds
 * @param {number} ms
 */

Promise.prototype.delay = function (ms) {
  return this.then(function (val) {
    return delay(val, ms)
  })
}

/**
 * Return a promise which will evaluate the function fn in a future turn with
 * the provided args
 *
 * @param {function(...)} fn
 * @param {...*} var_args a variable number of arguments
 * @return {!Promise}
 */

function fcall(fn, var_args) {
  var rootArgs = Array.prototype.slice.call(arguments, 1)
  var defer = new Promise()
  process.nextTick(function onNextTick() {
    try {
      defer.resolve(fn.apply(undefined, rootArgs))
    } catch (e) {
      defer.reject(e)
    }
  })
  return defer
}


/**
 * Returns a promise that will be invoked with the result of a node style
 * callback. All args to fn should be given except for the final callback arg
 *
 * @param {function(...)} fn
 * @param {...*} var_args a variable number of arguments
 * @return {!Promise}
 */

function nfcall(fn, var_args) {
  // Insert an undefined argument for scope and let bindPromise() do the work.
  var args = Array.prototype.slice.call(arguments, 0)
  args.splice(1, 0, undefined)
  return bindPromise.apply(undefined, args)()
}


/**
 * Binds a function to a scope with an optional number of curried arguments. Attaches
 * a node style callback as the last argument and returns a promise
 *
 * @param {function(...)} fn
 * @param {Object} scope
 * @param {...*} var_args a variable number of arguments
 * @return {function(...)}: !Promise}
 */

function bindPromise(fn, scope, var_args) {
  var rootArgs = Array.prototype.slice.call(arguments, 2)
  return function onBoundPromise(var_args) {
    var defer = new Promise()
    try {
      fn.apply(scope, rootArgs.concat(Array.prototype.slice.call(arguments, 0), defer.makeNodeResolver()))
    } catch (e) {
      defer.reject(e)
    }
    return defer
  }
}

kew = {
    all: all
  , bindPromise: bindPromise
  , defer: defer
  , delay: delay
  , fcall: fcall
  , isPromise: isPromise
  , isPromiseLike: isPromiseLike
  , nfcall: nfcall
  , resolve: resolve
  , reject: reject
  , allSettled: allSettled
}
return kew;
}())
</script>
<script>
//MyDeferred, MyPromise
(function (){
        function _then(promise, method, callback){
                return function (){
                        var args = arguments;

                        if( typeof callback === 'function' ){
                                var retVal = callback.apply(promise, args);
                                if( retVal && typeof retVal.then === 'function' ){
                                        retVal.done(promise.resolve).fail(promise.reject);
                                        return;
                                }
                        }

                        promise[method].apply(promise, args);
                };
        }



        /**
         * Fastest Deferred.
         * @returns {Deferred}
         */

        var Deferred = function (){
                var
                        _args,
                        _doneFn = [],
                        _failFn = [],

                        dfd = {
                                done: function (fn){
                                        _doneFn.push(fn);
                                        return dfd;
                                },

                                fail: function (fn){
                                        _failFn.push(fn);
                                        return dfd;
                                },

                                then: function (doneFn, failFn){
                                        var promise = Deferred();

                                        dfd
                                                .done(_then(promise, 'resolve', doneFn))
                                                .fail(_then(promise, 'reject', failFn))
                                        ;

                                        return promise;
                                },

                                always: function (fn){
                                        return dfd.done(fn).fail(fn);
                                },

                                resolve: _setState(true),
                                reject: _setState(false)
                        }
                ;


                function _setState(state){
                        return function (){
                                _args = arguments;

                                dfd.done =
                                dfd.fail =
                                dfd.resolve =
                                dfd.reject = function (){
                                        return dfd;
                                };

                                dfd[state ? 'done' : 'fail'] = function (fn){
                                        if( typeof fn === 'function' ){
                                                fn.apply(dfd, _args);
                                        }
                                        return dfd;
                                };

                                var
                                          fn
                                        , fns = state ? _doneFn : _failFn
                                        , i = 0, n = fns.length
                                ;

                                for( ; i < n; i++ ){
                                        fn = fns[i];
                                        if( typeof fn === 'function' ){
                                                fn.apply(dfd, _args);
                                        }
                                }

                                fns = _doneFn = _failFn = null;

                                return dfd;
                        }
                }

                return dfd;
        };


        /**
         * @param {Array} args
         * @returns {defer|*}
         */

        Deferred.when = function (args){
                var
                          dfd = Deferred()
                        , d
                        , i = args.length
                        , remain = i || 1
                        , _doneFn = function (){
                                if( --remain === 0 ){
                                        dfd.resolve();
                                }
                        }
                ;

                if( i === 0 ){
                        _doneFn();
                }
                else {
                        while( i-- ){
                                d = args[i];
                                if( d && d.then ){
                                        d.then(_doneFn, dfd.reject);
                                }
                        }
                }

                return dfd;
        };


        // exports
  window.MyDeferred = Deferred;
})();
window.MyPromise = function(){
  var global = Function('return this')();
  var isObject = function (arg) {
        return typeof arg === 'object' &&
            arg !== null;
    };
  var isFunction = function (arg) {
        return typeof arg === 'function';
    };
  var isObjectOrFunction = function (arg) {
        return isObject(arg) || isFunction(arg);
    };
  var isNative = function (target) {
        return typeof target === 'object' ||
            (target + '').slice(-17) === '{ [native code] }';
    };
  var final_ = function (initialiser, value) {
        return function () {
            if (initialiser !== null) {
                value = initialiser(value);
                initialiser = null;
            }
            return value;
        };
    };
  var scheduleMicrotask = function () {

    var finalSchedule = function () {
        var queue = [];

        function flushQueue() {
            var tasks = queue;
            queue = [];
            for (var i = 0; i < tasks.length; i++) {
                tasks[i]();
            }
        }

        function usePromise() {
            return null;
            if (!isNative(global.Promise)) {
                return null;
            }
            var fulfilled = new Promise(function (resolve) {
                resolve();
            });
            return function () {
                fulfilled.then(flushQueue);
            };
        }

        function useMutationObserver() {
            if (!isNative(global.MutationObserver)) {
                return null;
            }
            var iterations = 0;
            var observer = new MutationObserver(flushQueue);
            var node = document.createTextNode('');
            observer.observe(node, { characterData: true });
            return function() {
                node.data = (iterations = ++iterations % 2);
            };
        }

        function useSetImmediate() {
            if (!isNative(global.setImmediate)) {
                return null;
            }

            var immediateId;
            var timerId;
            function raceFlush() {
                clearTimeout(timerId);
                clearImmediate(immediateId);
                flushQueue();
            }
            return function () {
                immediateId = setImmediate(raceFlush);
                timerId = setTimeout(raceFlush);
            };
        }

        function useSetTimeout() {
            return function () {
                setTimeout(flushQueue);
            };
        }

        var scheduleFlush = usePromise() ||
            useMutationObserver() ||
            useSetImmediate() ||
            useSetTimeout();

        return function (callback) {
            queue.push(callback);
            if (queue.length <= 1) {
                scheduleFlush();
            }
        };
    }();

    return function (callback) {
        finalSchedule(callback);
    };
  }();
return function () {
        var PENDING = 0;
        var FULFILLED = 1;
        var REJECTED = 2;

        function Promise(resolver) {
           this._state = PENDING;
           this._value = [];
            var promise = this;
            try {
                resolver(function (value) {
                    resolve(promise, value);
                }, function (reason) {
                    reject(promise, reason);
                });
            } catch (ex) {
                reject(promise, ex);
            }
        }

        function Promise2() {
           this._state = PENDING;
           this._value = [];
        }
        Promise2.prototype = Promise.prototype;

        Promise.prototype._state = PENDING;
        Promise.prototype._value = '';

        function invokeCallback(settled, value, callback, promise) {
            if (isFunction(callback)) {
                try {
                    resolve(promise, callback(value));
                } catch (ex) {
                    reject(promise, ex);
                }
            } else {
                publish(promise, settled, value);
            }
        }

        function publish(promise, settled, value) {
            var subscribers = promise._value;
            promise._state = settled;
            promise._value = value;
            for (var i = 0; i < subscribers.length; i += 3) {
                invokeCallback(
                    settled,
                    value,
                    subscribers[i + settled],
                    subscribers[i]);
            }
        }

        function schedulePublish(promise, state, value) {
            scheduleMicrotask(function () {
                publish(promise, state, value);
            });
        }

        function isThenable(value) {
            return isObjectOrFunction(value) &&
                isFunction(value.then);
        }

        function chainThenable(thenable, promise) {
            try {
                thenable.then(function (value) {
                    resolve(promise, value);
                }, function (reason) {
                    reject(promise, reason);
                });
            } catch (ex) {
                reject(promise, ex);
            }
        }

        function resolve(promise, value) {
            if (value !== this && isThenable(value)) {
                chainThenable(value, promise);
            } else {
                schedulePublish(promise, FULFILLED, value);
            }
        }

        function reject(promise, reason) {
            schedulePublish(promise, REJECTED, reason);
        }

        Promise.prototype.then = function (onFulfilled, onRejected) {
            var childPromise = new Promise2();
            if (this._state <= PENDING) {
               
                    this._value.push(childPromise);
                    this._value.push(onFulfilled);
                    this._value.push(onRejected);
            } else {
                var callback = (this._state >= REJECTED) ?
                    onRejected : onFulfilled;
                if (!isFunction(callback)) {
                    publish(childPromise, this._state, this._value);
                } else {
                    var promise = this;
                    scheduleMicrotask(function () {
                        invokeCallback(
                            promise._state,
                            promise._value,
                            callback,
                            childPromise);
                    });
                }
            }
            return childPromise;
        };
        window.MyPromise2 = Promise2;
        window.resolveMyPromise = resolve;
        return Promise;
    }();
}();
</script>
<script>
require=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){"use strict";var callable=require("es5-ext/object/valid-callable"),d=require("d"),isCallable=require("es5-ext/object/is-callable"),ee=require("event-emitter"),isPromise=require("./is-promise"),create=Object.create,defineProperty=Object.defineProperty,deferred,resolve,reject;module.exports=exports=function(name,unres,onres,res){name=String(name);callable(res)&&(onres==null||callable(onres))&&callable(unres);defineProperty(exports._unresolved,name,d(unres));exports._onresolve[name]=onres;defineProperty(exports._resolved,name,d(res));exports._names.push(name)};exports._names=["done","then","valueOf"];exports._unresolved=ee(create(Function.prototype,{then:d(function(win,fail){var def;if(!this.pending)this.pending=[];def=deferred();this.pending.push("then",[win,fail,def.resolve,def.reject]);return def.promise}),done:d(function(win,fail){win==null||callable(win);fail==null||callable(fail);if(!this.pending)this.pending=[];this.pending.push("done",arguments)}),resolved:d(false),returnsPromise:d(true),valueOf:d(function(){return this})}));exports._onresolve={then:function(win,fail,resolve,reject){var value,cb=this.failed?fail:win;if(cb==null){if(this.failed)reject(this.value);else resolve(this.value);return}if(isCallable(cb)){if(isPromise(cb)){if(cb.resolved){if(cb.failed)reject(cb.value);else resolve(cb.value);return}cb.done(resolve,reject);return}try{value=cb(this.value)}catch(e){reject(e);return}resolve(value);return}resolve(cb)},done:function(win,fail){if(this.failed){if(fail){fail(this.value);return}throw this.value}if(win)win(this.value)}};exports._resolved=ee(create(Function.prototype,{then:d(function(win,fail){var value,cb=this.failed?fail:win;if(cb==null)return this;if(isCallable(cb)){if(isPromise(cb))return cb;try{value=cb(this.value)}catch(e){return reject(e)}return resolve(value)}return resolve(cb)}),done:d(function(win,fail){win==null||callable(win);fail==null||callable(fail);if(this.failed){if(fail){fail(this.value);return}throw this.value}if(win)win(this.value)}),resolved:d(true),returnsPromise:d(true),valueOf:d(function(){return this.value})}));deferred=require("./deferred");resolve=deferred.resolve;reject=deferred.reject;deferred.extend=exports},{"./deferred":"/IKIa2","./is-promise":5,d:6,"es5-ext/object/is-callable":12,"es5-ext/object/valid-callable":18,"event-emitter":23}],2:[function(require,module,exports){"use strict";var isObject=require("es5-ext/object/is-object"),isPromise=require("./is-promise"),deferred=require("./deferred"),nextTick=require("next-tick"),getPrototypeOf=Object.getPrototypeOf;module.exports=function self(value){var then,done,def,resolve,reject;if(!value)return value;try{then=value.then}catch(e){return value}if(typeof then!=="function")return value;if(isPromise(value))return value;if(!isObject(value))return value;if(!getPrototypeOf(value))return value;try{done=value.done}catch(ignore){}def=deferred();resolve=function(value){def.resolve(self(value))};reject=function(value){def.reject(value)};if(typeof done==="function"){try{done.call(value,resolve,reject)}catch(e){return def.reject(e)}return def.promise}try{then.call(value,function(value){nextTick(function(){resolve(value)})},function(value){nextTick(function(){reject(value)})})}catch(e){return def.reject(e)}return def.promise}},{"./deferred":"/IKIa2","./is-promise":5,"es5-ext/object/is-object":13,"next-tick":24}],deferred:[function(require,module,exports){module.exports=require("/IKIa2")},{}],"/IKIa2":[function(require,module,exports){"use strict";var isError=require("es5-ext/error/is-error"),noop=require("es5-ext/function/noop"),isPromise=require("./is-promise"),every=Array.prototype.every,push=Array.prototype.push,Deferred,createDeferred,count=0,timeout,extendShim,ext,protoSupported=Boolean(isPromise.__proto__),resolve,assimilate;extendShim=function(promise){ext._names.forEach(function(name){promise[name]=function(){return promise.__proto__[name].apply(promise,arguments)}});promise.returnsPromise=true;promise.resolved=promise.__proto__.resolved};resolve=function(value,failed){var promise=function(win,fail){return promise.then(win,fail)};promise.value=value;promise.failed=failed;promise.__proto__=ext._resolved;if(!protoSupported){extendShim(promise)}if(createDeferred._profile)createDeferred._profile(true);return promise};Deferred=function(){var promise=function(win,fail){return promise.then(win,fail)};if(!count)timeout=setTimeout(noop,1e9);++count;if(createDeferred._monitor)promise.monitor=createDeferred._monitor();promise.__proto__=ext._unresolved;if(!protoSupported)extendShim(promise);createDeferred._profile&&createDeferred._profile();this.promise=promise;this.resolve=this.resolve.bind(this);this.reject=this.reject.bind(this)};Deferred.prototype={resolved:false,_settle:function(value){var i,name,data;this.promise.value=value;this.promise.__proto__=ext._resolved;if(!protoSupported)this.promise.resolved=true;if(this.promise.dependencies){this.promise.dependencies.forEach(function self(dPromise){dPromise.value=value;dPromise.failed=this.failed;dPromise.__proto__=ext._resolved;if(!protoSupported)dPromise.resolved=true;delete dPromise.pending;if(dPromise.dependencies){dPromise.dependencies.forEach(self,this);delete dPromise.dependencies}},this.promise);delete this.promise.dependencies}if(data=this.promise.pending){for(i=0;name=data[i];++i){ext._onresolve[name].apply(this.promise,data[++i])}delete this.promise.pending}return this.promise},resolve:function(value){if(this.resolved)return this.promise;this.resolved=true;if(!--count)clearTimeout(timeout);if(this.promise.monitor)clearTimeout(this.promise.monitor);value=assimilate(value);if(isPromise(value)){if(!value.resolved){if(!value.dependencies){value.dependencies=[]}value.dependencies.push(this.promise);if(this.promise.pending){if(value.pending){push.apply(value.pending,this.promise.pending);this.promise.pending=value.pending;if(this.promise.dependencies){this.promise.dependencies.forEach(function self(dPromise){dPromise.pending=value.pending;if(dPromise.dependencies){dPromise.dependencies.forEach(self)}})}}else{value.pending=this.promise.pending}}else if(value.pending){this.promise.pending=value.pending}else{this.promise.pending=value.pending=[]}return this.promise}this.promise.failed=value.failed;value=value.value}return this._settle(value)},reject:function(error){if(this.resolved)return this.promise;this.resolved=true;if(!--count)clearTimeout(timeout);if(this.promise.monitor)clearTimeout(this.promise.monitor);this.promise.failed=true;return this._settle(error)}};module.exports=createDeferred=function(value){var l=arguments.length,d,waiting,initialized,result;if(!l)return new Deferred;if(l>1){d=new Deferred;waiting=0;result=new Array(l);every.call(arguments,function(value,index){value=assimilate(value);if(!isPromise(value)){result[index]=value;return true}if(value.resolved){if(value.failed){d.reject(value.value);return false}result[index]=value.value;return true}++waiting;value.done(function(value){result[index]=value;if(!--waiting&&initialized)d.resolve(result)},d.reject);return true});initialized=true;if(!waiting)d.resolve(result);return d.promise}value=assimilate(value);if(isPromise(value))return value;return resolve(value,isError(value))};createDeferred.Deferred=Deferred;createDeferred.reject=function(value){return resolve(value,true)};createDeferred.resolve=function(value){value=assimilate(value);if(isPromise(value))return value;return resolve(value,false)};ext=require("./_ext");assimilate=require("./assimilate")},{"./_ext":1,"./assimilate":2,"./is-promise":5,"es5-ext/error/is-error":7,"es5-ext/function/noop":8}],5:[function(require,module,exports){"use strict";module.exports=function(o){return typeof o==="function"&&typeof o.then==="function"}},{}],6:[function(require,module,exports){"use strict";var assign=require("es5-ext/object/assign"),normalizeOpts=require("es5-ext/object/normalize-options"),isCallable=require("es5-ext/object/is-callable"),contains=require("es5-ext/string/#/contains"),d;d=module.exports=function(dscr,value){var c,e,w,options,desc;if(arguments.length<2||typeof dscr!=="string"){options=value;value=dscr;dscr=null}else{options=arguments[2]}if(dscr==null){c=w=true;e=false}else{c=contains.call(dscr,"c");e=contains.call(dscr,"e");w=contains.call(dscr,"w")}desc={value:value,configurable:c,enumerable:e,writable:w};return!options?desc:assign(normalizeOpts(options),desc)};d.gs=function(dscr,get,set){var c,e,options,desc;if(typeof dscr!=="string"){options=set;set=get;get=dscr;dscr=null}else{options=arguments[3]}if(get==null){get=undefined}else if(!isCallable(get)){options=get;get=set=undefined}else if(set==null){set=undefined}else if(!isCallable(set)){options=set;set=undefined}if(dscr==null){c=true;e=false}else{c=contains.call(dscr,"c");e=contains.call(dscr,"e")}desc={get:get,set:set,configurable:c,enumerable:e};return!options?desc:assign(normalizeOpts(options),desc)}},{"es5-ext/object/assign":9,"es5-ext/object/is-callable":12,"es5-ext/object/normalize-options":17,"es5-ext/string/#/contains":20}],7:[function(require,module,exports){"use strict";var toString=Object.prototype.toString,id=toString.call(new Error);module.exports=function(x){return x&&(x instanceof Error||toString.call(x)===id)||false}},{}],8:[function(require,module,exports){"use strict";module.exports=function(){}},{}],9:[function(require,module,exports){"use strict";module.exports=require("./is-implemented")()?Object.assign:require("./shim")},{"./is-implemented":10,"./shim":11}],10:[function(require,module,exports){"use strict";module.exports=function(){var assign=Object.assign,obj;if(typeof assign!=="function")return false;obj={foo:"raz"};assign(obj,{bar:"dwa"},{trzy:"trzy"});return obj.foo+obj.bar+obj.trzy==="razdwatrzy"}},{}],11:[function(require,module,exports){"use strict";var keys=require("../keys"),value=require("../valid-value"),max=Math.max;module.exports=function(dest,src){var error,i,l=max(arguments.length,2),assign;dest=Object(value(dest));assign=function(key){try{dest[key]=src[key]}catch(e){if(!error)error=e}};for(i=1;i<l;++i){src=arguments[i];keys(src).forEach(assign)}if(error!==undefined)throw error;return dest}},{"../keys":14,"../valid-value":19}],12:[function(require,module,exports){"use strict";module.exports=function(obj){return typeof obj==="function"}},{}],13:[function(require,module,exports){"use strict";var map={"function":true,object:true};module.exports=function(x){return x!=null&&map[typeof x]||false}},{}],14:[function(require,module,exports){"use strict";module.exports=require("./is-implemented")()?Object.keys:require("./shim")},{"./is-implemented":15,"./shim":16}],15:[function(require,module,exports){"use strict";module.exports=function(){try{Object.keys("primitive");return true}catch(e){return false}}},{}],16:[function(require,module,exports){"use strict";var keys=Object.keys;module.exports=function(object){return keys(object==null?object:Object(object))}},{}],17:[function(require,module,exports){"use strict";var assign=require("./assign"),forEach=Array.prototype.forEach,create=Object.create,getPrototypeOf=Object.getPrototypeOf,process;process=function(src,obj){var proto=getPrototypeOf(src);return assign(proto?process(proto,obj):obj,src)};module.exports=function(options){var result=create(null);forEach.call(arguments,function(options){if(options==null)return;process(Object(options),result)});return result}},{"./assign":9}],18:[function(require,module,exports){"use strict";module.exports=function(fn){if(typeof fn!=="function")throw new TypeError(fn+" is not a function");return fn}},{}],19:[function(require,module,exports){"use strict";module.exports=function(value){if(value==null)throw new TypeError("Cannot use null or undefined");return value}},{}],20:[function(require,module,exports){"use strict";module.exports=require("./is-implemented")()?String.prototype.contains:require("./shim")},{"./is-implemented":21,"./shim":22}],21:[function(require,module,exports){"use strict";var str="razdwatrzy";module.exports=function(){if(typeof str.contains!=="function")return false;return str.contains("dwa")===true&&str.contains("foo")===false}},{}],22:[function(require,module,exports){"use strict";var indexOf=String.prototype.indexOf;module.exports=function(searchString){return indexOf.call(this,searchString,arguments[1])>-1}},{}],23:[function(require,module,exports){"use strict";var d=require("d"),callable=require("es5-ext/object/valid-callable"),apply=Function.prototype.apply,call=Function.prototype.call,create=Object.create,defineProperty=Object.defineProperty,defineProperties=Object.defineProperties,hasOwnProperty=Object.prototype.hasOwnProperty,descriptor={configurable:true,enumerable:false,writable:true},on,once,off,emit,methods,descriptors,base;on=function(type,listener){var data;callable(listener);if(!hasOwnProperty.call(this,"__ee__")){data=descriptor.value=create(null);defineProperty(this,"__ee__",descriptor);descriptor.value=null}else{data=this.__ee__}if(!data[type])data[type]=listener;else if(typeof data[type]==="object")data[type].push(listener);else data[type]=[data[type],listener];return this};once=function(type,listener){var once,self;callable(listener);self=this;on.call(this,type,once=function(){off.call(self,type,once);apply.call(listener,this,arguments)});once.__eeOnceListener__=listener;return this};off=function(type,listener){var data,listeners,candidate,i;callable(listener);if(!hasOwnProperty.call(this,"__ee__"))return this;data=this.__ee__;if(!data[type])return this;listeners=data[type];if(typeof listeners==="object"){for(i=0;candidate=listeners[i];++i){if(candidate===listener||candidate.__eeOnceListener__===listener){if(listeners.length===2)data[type]=listeners[i?0:1];else listeners.splice(i,1)}}}else{if(listeners===listener||listeners.__eeOnceListener__===listener){delete data[type]}}return this};emit=function(type){var i,l,listener,listeners,args;if(!hasOwnProperty.call(this,"__ee__"))return;listeners=this.__ee__[type];if(!listeners)return;if(typeof listeners==="object"){l=arguments.length;args=new Array(l-1);for(i=1;i<l;++i)args[i-1]=arguments[i];listeners=listeners.slice();for(i=0;listener=listeners[i];++i){apply.call(listener,this,args)}}else{switch(arguments.length){case 1:call.call(listeners,this);break;case 2:call.call(listeners,this,arguments[1]);break;case 3:call.call(listeners,this,arguments[1],arguments[2]);break;default:l=arguments.length;args=new Array(l-1);for(i=1;i<l;++i){args[i-1]=arguments[i]}apply.call(listeners,this,args)}}};methods={on:on,once:once,off:off,emit:emit};descriptors={on:d(on),once:d(once),off:d(off),emit:d(emit)};base=defineProperties({},descriptors);module.exports=exports=function(o){return o==null?create(base):defineProperties(Object(o),descriptors)};exports.methods=methods},{d:6,"es5-ext/object/valid-callable":18}],24:[function(require,module,exports){(function(process){"use strict";var callable,byObserver;callable=function(fn){if(typeof fn!=="function")throw new TypeError(fn+" is not a function");return fn};byObserver=function(Observer){var node=document.createTextNode(""),queue,i=0;new Observer(function(){var data;if(!queue)return;data=queue;queue=null;if(typeof data==="function"){data();return}data.forEach(function(fn){fn()})}).observe(node,{characterData:true});return function(fn){callable(fn);if(queue){if(typeof queue==="function")queue=[queue,fn];else queue.push(fn);return}queue=fn;node.data=i=++i%2}};module.exports=function(){if(typeof process!=="undefined"&&process&&typeof process.nextTick==="function"){return process.nextTick}if(typeof document==="object"&&document){if(typeof MutationObserver==="function"){return byObserver(MutationObserver)}if(typeof WebKitMutationObserver==="function"){return byObserver(WebKitMutationObserver)}}if(typeof setImmediate==="function"){return function(cb){setImmediate(callable(cb))}}if(typeof setTimeout==="function"){return function(cb){setTimeout(callable(cb),0)}}return null}()}).call(this,require("lppjwH"))},{lppjwH:25}],25:[function(require,module,exports){var process=module.exports={};process.nextTick=function(){var canSetImmediate=typeof window!=="undefined"&&window.setImmediate;var canPost=typeof window!=="undefined"&&window.postMessage&&window.addEventListener;if(canSetImmediate){return function(f){return window.setImmediate(f)}}if(canPost){var queue=[];window.addEventListener("message",function(ev){var source=ev.source;if((source===window||source===null)&&ev.data==="process-tick"){ev.stopPropagation();if(queue.length>0){var fn=queue.shift();fn()}}},true);return function nextTick(fn){queue.push(fn);window.postMessage("process-tick","*")}}return function nextTick(fn){setTimeout(fn,0)}}();process.title="browser";process.browser=true;process.env={};process.argv=[];function noop(){}process.on=noop;process.addListener=noop;process.once=noop;process.off=noop;process.removeListener=noop;process.removeAllListeners=noop;process.emit=noop;process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")}},{}]},{},[]);
</script>
<script>
var deferredjs = require('deferred');
function runInConsole(){
var suite = new Benchmark.Suite;
console.log('Async test run started!...');
// add tests
suite.add('lie', function() {
  var d = lie();
var code = 'lie' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();
  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
 
})
window.postMessage(code, '*');
})
.add('when', function() {var x = 1;
var d = when.defer()
var code = 'when' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
 
})
window.postMessage(code, '*');
})
.add('kew', function() {var d = K.defer()
var code = 'k' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
 
})
window.postMessage(code, '*');
})
.add('q', function() {
var d = Q.defer()
var code = 'q' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
 
})
window.postMessage(code, '*');
})
.add('catiline', function() {var d = cw.deferred()
var code = 'cw' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
 
})
window.postMessage(code, '*');
})
.add('bluebird', function() {var d = BluebirdPromise.pending();
var code = 'pend' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.fulfill();

  }
}

d.promise.then(function() {
 
});
window.addEventListener('message', eventFunc);
window.postMessage(code, '*');
})
.add('pimp', function() {var d = Pimp.deferred()
var code = 'pimp' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
 
})
window.postMessage(code, '*');
})
.add('RSVP', function() {var d = RSVP.defer();
var code = 'rsvp' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
 
})
window.postMessage(code, '*');
})
.add('MyDeferred', function() {var d = MyDeferred();
var code = 'myDef' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.then(function() {
 
})
window.postMessage(code, '*');
})
.add('MyPromise2', function() {var d = new MyPromise2();
var code = 'MyPr' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    resolveMyPromise(d);

  }
}
window.addEventListener('message', eventFunc);
d.then(function() {
 
})
window.postMessage(code, '*');
})
.add('deferredjs', function() {
var d = deferred();
var code = 'defjs' + Math.random();
function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();
  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  deferred.resolve()
})
window.postMessage(code, '*');
})
// add listeners
.on('cycle', function(event) {
  console.log(String(event.target));
})
.on('complete', function() {
  console.log('Fastest is ' + this.filter('fastest').pluck('name'));
})
// run async
.run({ 'async': true });
}
</script>
<button onclick="runInConsole()">Run async tests in console</button>

Preparation code output

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
lie
var d = lie();
var code = 'lie' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();
  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  return 'done'
})
window.postMessage(code, '*');
 
pending…
lie async
// async test
var d = lie();
var code = 'lie' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();
  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  deferred.resolve()
})
window.postMessage(code, '*');
pending…
when
var x = 1;
var d = when.defer()
var code = 'when' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  return 'done'
})
window.postMessage(code, '*');
pending…
when async
// async test
var x = 1;
var d = when.defer()
var code = 'when' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  deferred.resolve()
})
window.postMessage(code, '*');
pending…
Kew
var d = K.defer()
var code = 'k' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  return 'done'
})
window.postMessage(code, '*');
pending…
Kew async
// async test
var d = K.defer()
var code = 'k' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  deferred.resolve()
})
window.postMessage(code, '*');
pending…
Q
var d = Q.defer()
var code = 'q' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  return 'done'
})
window.postMessage(code, '*');
pending…
Q async
// async test
var d = Q.defer()
var code = 'q' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  deferred.resolve()
})
window.postMessage(code, '*');
pending…
catiline
var d = cw.deferred()
var code = 'cw' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  return 'done'
})
window.postMessage(code, '*');
pending…
catiline async
// async test
var d = cw.deferred()
var code = 'cw' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  deferred.resolve()
})
window.postMessage(code, '*');
pending…
bluebird
var d = BluebirdPromise.pending();
var code = 'pend' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.fulfill();

  }
}

d.promise.then(function() {
  return 'done'
});
window.addEventListener('message', eventFunc);
window.postMessage(code, '*');
pending…
bluebird async
// async test
var d = BluebirdPromise.pending();
var code = 'pend' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.fulfill();

  }
}

d.promise.then(function() {
  deferred.resolve()
});
window.addEventListener('message', eventFunc);
window.postMessage(code, '*');
pending…
Pimp
var d = Pimp.deferred()
var code = 'pimp' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  return 'done'
})
window.postMessage(code, '*');
pending…
Pimp async
// async test
var d = Pimp.deferred()
var code = 'pimp' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  deferred.resolve()
})
window.postMessage(code, '*');
pending…
RSVP
var d = RSVP.defer();
var code = 'rsvp' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  return 'done'
})
window.postMessage(code, '*');
pending…
RSVP async
// async test
var d = RSVP.defer();
var code = 'rsvp' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  deferred.resolve()
})
window.postMessage(code, '*');
pending…
MyDeferred
var d = MyDeferred();
var code = 'myDef' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.then(function() {
  return 'done'
})
window.postMessage(code, '*');
pending…
MyDeferred async
// async test
var d = MyDeferred();
var code = 'myDef' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.then(function() {
  deferred.resolve()
})
window.postMessage(code, '*');
pending…
MyPromise2
var d = new MyPromise2();
var code = 'MyPr' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    resolveMyPromise(d);

  }
}
window.addEventListener('message', eventFunc);
d.then(function() {
  return 'done'
})
window.postMessage(code, '*');
pending…
MyPromise2 async
// async test
var d = new MyPromise2();
var code = 'MyPr' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    resolveMyPromise(d);

  }
}
window.addEventListener('message', eventFunc);
d.then(function() {
  deferred.resolve()
})
window.postMessage(code, '*');
pending…
deferredjs
var d = deferredjs();
var code = 'defjs' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  return 'done'
})
window.postMessage(code, '*');
pending…
deferredjs async
// async test
var d = deferredjs();
var code = 'defjs' + Math.random();

function eventFunc(e) {
  if (e.data === code) {
    window.removeEventListener('message', eventFunc);
    d.resolve();

  }
}
window.addEventListener('message', eventFunc);
d.promise.then(function() {
  deferred.resolve()
})
window.postMessage(code, '*');
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL. Here’s a list of current revisions for this page:

0 comments

Add a comment