UNPKG

headq

Version:

lightweight javascript promise library

269 lines (207 loc) 5.76 kB
(function() { 'use strict'; var isArray = Array.isArray; if (!isArray) { isArray = function(arg) { return (Object.prototype.toString.call(arg) === '[object Array]'); }; } function isFunction(arg) { return (typeof(arg) === 'function'); } var delayedCall = null; if (typeof(window) !== 'undefined') { if (isFunction(window.setImmediate)) { delayedCall = window.setImmediate; } } else { if (isFunction(setImmediate)) { delayedCall = setImmediate; } else { if (typeof(process) !== 'undefined' && isFunction(process.nextTick)) { delayedCall = process.nextTick; } } } function asyncCall(callback) { if (isFunction(delayedCall)) { return delayedCall(callback); } else { return setTimeout(callback, 0); } } function Promise() { } Promise.prototype.then = function(onResolve, onReject, onNotify) { var self = this; if (isFunction(onResolve)) { if (!isArray(self.onresolve)) { self.onresolve = []; } self.onresolve.push(onResolve); } if (isFunction(onReject)) { if (!isArray(self.onreject)) { self.onreject = []; } self.onreject.push(onReject); } if (isFunction(onNotify)) { if (!isArray(self.onnotify)) { self.onnotify = []; } self.onnotify.push(onNotify); } return self; }; Promise.prototype.catch = function(onError) { var self = this; if (isFunction(onError)) { if (!isArray(self.onreject)) { self.onreject = []; } self.onreject.push(onError); } return self; }; Promise.prototype.finally = function(onResolve, onNotify) { var self = this; return self.then(function() { onResolve(); }, function() { onResolve(); }, onNotify); }; function Defer() { this.promise = new Promise(); } Defer.prototype.then = function(onResolve, onReject, onNotify) { return this.promise.then(onResolve, onReject, onNotify); }; Defer.prototype.catch = function(onError) { return this.promise.catch(onError); }; Defer.prototype.finally = function(onResolve, onNotify) { return this.promise.finally(onResolve, onNotify); }; Defer.prototype.resolve = function(arg) { var self = this; asyncCall(function() { if (isArray(self.promise.onresolve) && !self.rejected) { var callbacks = self.promise.onresolve; callbacks.forEach(function(callback) { try { callback.call(self, arg); } catch(ignored) {} }); self.promise.onresolve = null; self.promise.onreject = null; self.promise.onnotify = null; } }); return self.promise; }; Defer.prototype.reject = function(arg) { var self = this; self.rejected = true; asyncCall(function() { if (isArray(self.promise.onreject)) { var callbacks = self.promise.onreject; callbacks.forEach(function(callback) { try { callback.call(self, arg); } catch(ignored) {} }); } self.promise.onresolve = null; self.promise.onreject = null; self.promise.onnotify = null; }); return self.promise; }; Defer.prototype.notify = function(arg) { var self = this; asyncCall(function() { if (isArray(self.promise.onnotify)) { var callbacks = self.promise.onnotify; callbacks.forEach(function(callback) { try { callback.call(self, arg); } catch(ignored) {} }); } }); }; var $q = function(callback) { var req = new Defer(); function onResolve(data) { req.resolve(data); } function onReject(data) { req.reject(data); } function onNotify(data) { req.notify(data); } asyncCall(function() { try { callback(onResolve, onReject, onNotify); } catch(error) { req.reject(error); } }); return req.promise; } $q.defer = function() { return new Defer(); }; $q.when = function(arg, onResolve, onReject, onNotify) { if (arg && isFunction(arg.then)) { return arg.then.call(arg, onResolve, onReject, onNotify); } var req = new Defer(); req.resolve(arg); return req.promise; }; $q.resolve = $q.when; $q.reject = function(arg) { var req = new Defer(); req.reject(arg); return req.promise; }; $q.all = function(targets) { var req = new Defer(); var list = targets; var res = []; var len = 0; if (targets instanceof Promise) { list = [ targets ]; } try { len = list.length; if (len) { list.forEach(function(promise, index) { promise.then(function(arg) { len--; res[index] = arg; if (!len) { req.resolve(res); } }, function(error) { req.reject(error); }); }); } else { req.resolve([]); } } catch (error) { req.reject(error); } return req.promise; }; if (typeof(exports) !== 'undefined') { module.exports = $q; } else { window.$q = $q; } })();