diff --git a/src/WebComponents/Promise.js b/src/WebComponents/Promise.js index 7189f6c..f7925ad 100644 --- a/src/WebComponents/Promise.js +++ b/src/WebComponents/Promise.js @@ -1,184 +1,186 @@ (function() { - function MakePromise (asap) { - function Promise(fn) { - if (typeof this !== 'object' || typeof fn !== 'function') throw new TypeError(); - this._state = null; - this._value = null; - this._deferreds = [] + if (!window.Promise) { - doResolve(fn, resolve.bind(this), reject.bind(this)); - } + function MakePromise (asap) { + function Promise(fn) { + if (typeof this !== 'object' || typeof fn !== 'function') throw new TypeError(); + this._state = null; + this._value = null; + this._deferreds = [] - function handle(deferred) { - var me = this; - if (this._state === null) { - this._deferreds.push(deferred); - return - } - asap(function() { - var cb = me._state ? deferred.onFulfilled : deferred.onRejected - if (typeof cb !== 'function') { - (me._state ? deferred.resolve : deferred.reject)(me._value); - return; - } - var ret; - try { - ret = cb(me._value); - } - catch (e) { - deferred.reject(e); - return; - } - deferred.resolve(ret); - }) - } + doResolve(fn, resolve.bind(this), reject.bind(this)); + } - function resolve(newValue) { - try { //Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure - if (newValue === this) throw new TypeError(); - if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { - var then = newValue.then; - if (typeof then === 'function') { - doResolve(then.bind(newValue), resolve.bind(this), reject.bind(this)); - return; - } - } - this._state = true; - this._value = newValue; - finale.call(this); - } catch (e) { reject.call(this, e); } - } + function handle(deferred) { + var me = this; + if (this._state === null) { + this._deferreds.push(deferred); + return + } + asap(function() { + var cb = me._state ? deferred.onFulfilled : deferred.onRejected + if (typeof cb !== 'function') { + (me._state ? deferred.resolve : deferred.reject)(me._value); + return; + } + var ret; + try { + ret = cb(me._value); + } + catch (e) { + deferred.reject(e); + return; + } + deferred.resolve(ret); + }) + } - function reject(newValue) { - this._state = false; - this._value = newValue; - finale.call(this); - } + function resolve(newValue) { + try { //Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure + if (newValue === this) throw new TypeError(); + if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { + var then = newValue.then; + if (typeof then === 'function') { + doResolve(then.bind(newValue), resolve.bind(this), reject.bind(this)); + return; + } + } + this._state = true; + this._value = newValue; + finale.call(this); + } catch (e) { reject.call(this, e); } + } - function finale() { - for (var i = 0, len = this._deferreds.length; i < len; i++) { - handle.call(this, this._deferreds[i]); - } - this._deferreds = null; - } + function reject(newValue) { + this._state = false; + this._value = newValue; + finale.call(this); + } - /** - * Take a potentially misbehaving resolver function and make sure - * onFulfilled and onRejected are only called once. - * - * Makes no guarantees about asynchrony. - */ - function doResolve(fn, onFulfilled, onRejected) { - var done = false; - try { - fn(function (value) { - if (done) return; - done = true; - onFulfilled(value); - }, function (reason) { - if (done) return; - done = true; - onRejected(reason); - }) - } catch (ex) { - if (done) return; - done = true; - onRejected(ex); - } - } + function finale() { + for (var i = 0, len = this._deferreds.length; i < len; i++) { + handle.call(this, this._deferreds[i]); + } + this._deferreds = null; + } - Promise.prototype['catch'] = function (onRejected) { - return this.then(null, onRejected); - }; + /** + * Take a potentially misbehaving resolver function and make sure + * onFulfilled and onRejected are only called once. + * + * Makes no guarantees about asynchrony. + */ + function doResolve(fn, onFulfilled, onRejected) { + var done = false; + try { + fn(function (value) { + if (done) return; + done = true; + onFulfilled(value); + }, function (reason) { + if (done) return; + done = true; + onRejected(reason); + }) + } catch (ex) { + if (done) return; + done = true; + onRejected(ex); + } + } - Promise.prototype.then = function(onFulfilled, onRejected) { - var me = this; - return new Promise(function(resolve, reject) { - handle.call(me, { - onFulfilled: onFulfilled, - onRejected: onRejected, - resolve: resolve, - reject: reject - }); - }) - }; + Promise.prototype['catch'] = function (onRejected) { + return this.then(null, onRejected); + }; - Promise.resolve = function (value) { - if (value && typeof value === 'object' && value.constructor === Promise) { - return value; - } + Promise.prototype.then = function(onFulfilled, onRejected) { + var me = this; + return new Promise(function(resolve, reject) { + handle.call(me, { + onFulfilled: onFulfilled, + onRejected: onRejected, + resolve: resolve, + reject: reject + }); + }) + }; - return new Promise(function (resolve) { - resolve(value); - }); - }; + Promise.resolve = function (value) { + if (value && typeof value === 'object' && value.constructor === Promise) { + return value; + } - Promise.reject = function (value) { - return new Promise(function (resolve, reject) { - reject(value); - }); - }; + return new Promise(function (resolve) { + resolve(value); + }); + }; + + Promise.reject = function (value) { + return new Promise(function (resolve, reject) { + reject(value); + }); + }; - return Promise; - } + return Promise; + } - if (!window.Promise) { - function makeAsync() { - var twiddle = document.createTextNode(''); - var content = 0; - return function(callback) { - // To preserve timing with Promise microtasks - // we create a new observer for every callback. - var observer = new MutationObserver(function(mxns) { - observer.disconnect(); - callback(); - }); - observer.observe(twiddle, {characterData: true}); - twiddle.textContent = content++; - } - } - window.Promise = MakePromise(makeAsync()); + function makeAsync() { + var twiddle = document.createTextNode(''); + var content = 0; + return function(callback) { + // To preserve timing with Promise microtasks + // we create a new observer for every callback. + var observer = new MutationObserver(function(mxns) { + observer.disconnect(); + callback(); + }); + observer.observe(twiddle, {characterData: true}); + twiddle.textContent = content++; + } + } - window.Promise.all = function () { - var args = Array.prototype.slice.call(arguments.length === 1 && Array.isArray(arguments[0]) ? arguments[0] : arguments); + window.Promise = MakePromise(makeAsync()); - return new Promise(function (resolve, reject) { - if (args.length === 0) return resolve([]); - var remaining = args.length; - function res(i, val) { - try { - if (val && (typeof val === 'object' || typeof val === 'function')) { - var then = val.then; - if (typeof then === 'function') { - then.call(val, function (val) { res(i, val) }, reject); - return; - } - } - args[i] = val; - if (--remaining === 0) { - resolve(args); - } - } catch (ex) { - reject(ex); - } - } - for (var i = 0; i < args.length; i++) { - res(i, args[i]); - } - }); - }; + window.Promise.all = function () { + var args = Array.prototype.slice.call(arguments.length === 1 && Array.isArray(arguments[0]) ? arguments[0] : arguments); - window.Promise.race = function (values) { - return new Promise(function (resolve, reject) { - for(var i = 0, len = values.length; i < len; i++) { - values[i].then(resolve, reject); - } - }); - }; + return new Promise(function (resolve, reject) { + if (args.length === 0) return resolve([]); + var remaining = args.length; + function res(i, val) { + try { + if (val && (typeof val === 'object' || typeof val === 'function')) { + var then = val.then; + if (typeof then === 'function') { + then.call(val, function (val) { res(i, val) }, reject); + return; + } + } + args[i] = val; + if (--remaining === 0) { + resolve(args); + } + } catch (ex) { + reject(ex); + } + } + for (var i = 0; i < args.length; i++) { + res(i, args[i]); + } + }); + }; - } + window.Promise.race = function (values) { + return new Promise(function (resolve, reject) { + for(var i = 0, len = values.length; i < len; i++) { + values[i].then(resolve, reject); + } + }); + }; + + } })(); \ No newline at end of file