diff --git a/index.js b/index.js index 3a0c8e18..8467bd99 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,6 @@ "use strict" +var Promise = require("./promise/promise") var m = require("./render/hyperscript") var renderService = require("./render/render")(window) var redrawService = require("./api/pubsub")() diff --git a/promise/promise.js b/promise/promise.js index baf1090b..cf24f387 100644 --- a/promise/promise.js +++ b/promise/promise.js @@ -1,98 +1,98 @@ "use strict" -{ -function Promise(executor) { - if (!(this instanceof Promise)) throw new Error("Promise must be called with `new`") - if (typeof executor !== "function") throw new Error("executor must be a function") - - var self = this, resolvers = [], rejectors = [], resolveCurrent = handler(resolvers, true), rejectCurrent = handler(rejectors, false) - var instance = self._instance = {resolvers: resolvers, rejectors: rejectors} - var callAsync = typeof setImmediate === "function" ? setImmediate : setTimeout - function handler(list, shouldAbsorb) { - return function execute(value) { - var then - try { - if (shouldAbsorb && value != null && (typeof value === "object" || typeof value === "function") && typeof (then = value.then) === "function") { - if (value === self) throw new TypeError("Promise can't be resolved w/ itself") - executeOnce(then.bind(value)) - } - else { - callAsync(function() { - if (!shouldAbsorb && list.length === 0) console.error("Possible unhandled promise rejection:", value) - for (var i = 0; i < list.length; i++) list[i](value) - resolvers.length = 0, rejectors.length = 0 - instance.state = shouldAbsorb - instance.retry = function() {execute(value)} - }, 0) - } - } - catch (e) { - rejectCurrent(e) - } - } - } - function executeOnce(then) { - var runs = 0 - function run(fn) { - return function(value) { - if (runs++ > 0) return - fn(value) - } - } - var onerror = run(rejectCurrent) - try {then(run(resolveCurrent), onerror)} catch (e) {onerror(e)} - } - - executeOnce(executor) -} -Promise.prototype.then = function(onFulfilled, onRejection) { - var self = this, instance = self._instance - function handle(callback, list, next, state) { - list.push(function(value) { - if (typeof callback !== "function") next(value) - else try {resolveNext(callback(value))} catch (e) {if (rejectNext) rejectNext(e)} - }) - if (typeof instance.retry === "function" && state === instance.state) instance.retry() - } - var resolveNext, rejectNext - var promise = new Promise(function(resolve, reject) {resolveNext = resolve, rejectNext = reject}) - handle(onFulfilled, instance.resolvers, resolveNext, true), handle(onRejection, instance.rejectors, rejectNext, false) - return promise -} -Promise.prototype.catch = function(onRejection) { - return this.then(null, onRejection) -} -Promise.resolve = function(value) { - if (value instanceof Promise) return value - return new Promise(function(resolve, reject) {resolve(value)}) -} -Promise.reject = function(value) { - return new Promise(function(resolve, reject) {reject(value)}) -} -Promise.all = function(list) { - return new Promise(function(resolve, reject) { - var total = list.length, count = 0, values = [] - for (var i = 0; i < list.length; i++) { - new function(i) { - function consume(value) { - count++ - values[i] = value - if (count === total) resolve(values) - } - if (list[i] != null && (typeof list[i] === "object" || typeof list[i] === "function") && typeof list[i].then === "function") { - list[i].then(consume, reject) - } - else consume(list[i]) - }(i) - } - }) -} -Promise.race = function(list) { - return new Promise(function(resolve, reject) { - for (var i = 0; i < list.length; i++) { - list[i].then(resolve, reject) - } - }) -} +if (typeof Promise === "undefined") { + var Promise = function(executor) { + if (!(this instanceof Promise)) throw new Error("Promise must be called with `new`") + if (typeof executor !== "function") throw new TypeError("executor must be a function") + + var self = this, resolvers = [], rejectors = [], resolveCurrent = handler(resolvers, true), rejectCurrent = handler(rejectors, false) + var instance = self._instance = {resolvers: resolvers, rejectors: rejectors} + var callAsync = typeof setImmediate === "function" ? setImmediate : setTimeout + function handler(list, shouldAbsorb) { + return function execute(value) { + var then + try { + if (shouldAbsorb && value != null && (typeof value === "object" || typeof value === "function") && typeof (then = value.then) === "function") { + if (value === self) throw new TypeError("Promise can't be resolved w/ itself") + executeOnce(then.bind(value)) + } + else { + callAsync(function() { + if (!shouldAbsorb && list.length === 0) console.error("Possible unhandled promise rejection:", value) + for (var i = 0; i < list.length; i++) list[i](value) + resolvers.length = 0, rejectors.length = 0 + instance.state = shouldAbsorb + instance.retry = function() {execute(value)} + }, 0) + } + } + catch (e) { + rejectCurrent(e) + } + } + } + function executeOnce(then) { + var runs = 0 + function run(fn) { + return function(value) { + if (runs++ > 0) return + fn(value) + } + } + var onerror = run(rejectCurrent) + try {then(run(resolveCurrent), onerror)} catch (e) {onerror(e)} + } + + executeOnce(executor) + } + Promise.prototype.then = function(onFulfilled, onRejection) { + var self = this, instance = self._instance + function handle(callback, list, next, state) { + list.push(function(value) { + if (typeof callback !== "function") next(value) + else try {resolveNext(callback(value))} catch (e) {if (rejectNext) rejectNext(e)} + }) + if (typeof instance.retry === "function" && state === instance.state) instance.retry() + } + var resolveNext, rejectNext + var promise = new Promise(function(resolve, reject) {resolveNext = resolve, rejectNext = reject}) + handle(onFulfilled, instance.resolvers, resolveNext, true), handle(onRejection, instance.rejectors, rejectNext, false) + return promise + } + Promise.prototype.catch = function(onRejection) { + return this.then(null, onRejection) + } + Promise.resolve = function(value) { + if (value instanceof Promise) return value + return new Promise(function(resolve, reject) {resolve(value)}) + } + Promise.reject = function(value) { + return new Promise(function(resolve, reject) {reject(value)}) + } + Promise.all = function(list) { + return new Promise(function(resolve, reject) { + var total = list.length, count = 0, values = [] + for (var i = 0; i < list.length; i++) { + new function(i) { + function consume(value) { + count++ + values[i] = value + if (count === total) resolve(values) + } + if (list[i] != null && (typeof list[i] === "object" || typeof list[i] === "function") && typeof list[i].then === "function") { + list[i].then(consume, reject) + } + else consume(list[i]) + }(i) + } + }) + } + Promise.race = function(list) { + return new Promise(function(resolve, reject) { + for (var i = 0; i < list.length; i++) { + list[i].then(resolve, reject) + } + }) + } +} module.exports = Promise -} \ No newline at end of file