Skip to content

Instantly share code, notes, and snippets.

@mwgamera
Last active December 22, 2015 03:09
Show Gist options
  • Save mwgamera/6408413 to your computer and use it in GitHub Desktop.
Save mwgamera/6408413 to your computer and use it in GitHub Desktop.
// Small Promise with implicit state compatible with Promises/A+.
// klg, Sep 2013, WTFPL 2.
(function() {
"use strict";
/**
* Create new Promise using given function to schedule resolution
* of the Promise. Continuations that respectively fulfill and
* reject the Promise are passed to the setup function.
*
* @param {function(function(*),function(*))} setup
* @constructor
**/
function Promise(setup) {
var queue = [];
function defer(fun) {
queue.push(fun);
setTimeout(function() {
while (queue.length) {
queue.shift()();
}
}, 0);
}
function isPromise(x) {
return x && typeof x.then === "function";
}
function isFunction(x) {
return typeof x === "function";
}
function chain(fun, arg, fulfill, reject) {
try {
var x = fun(arg);
if (isPromise(x)) {
x.then(fulfill, reject);
} else {
fulfill(x);
}
} catch (e) {
reject(e);
}
}
function fcomp(first, next, fulfill, reject) {
return function(value) {
first(value);
chain(next, value, fulfill, reject);
};
}
function resolve(k, x) {
fulfill = reject = function() {};
then = function(onfulfill, onreject, fulfill2, reject2) {
defer(function() {
chain([onfulfill,onreject][k], x, fulfill2, reject2);
});
};
}
var fulfill = function(value) { resolve(0, value); };
var reject = function(reason) { resolve(1, reason); };
var then = function(onfulfill, onreject, fulfill2, reject2) {
fulfill = fcomp(fulfill, onfulfill, fulfill2, reject2);
reject = fcomp(reject, onreject, fulfill2, reject2);
};
var self = this || {};
/**
* Bind fulfillment and/or rejection callbacks.
*
* @param {?(function(*):*)=} onfulfill
* @param {?(function(*):*)=} onreject
* @return {!Promise}
* @expose
**/
self.then = function(onfulfill, onreject) {
if (!isFunction(onfulfill)) {
onfulfill = function(x) { return x; };
}
if (!isFunction(onreject)) {
onreject = function(x) { throw x; };
}
return new Promise(function(fulfill2, reject2) {
then(onfulfill, onreject, fulfill2, reject2);
});
};
setup.call(self, function(x) { fulfill(x); }, function(x) { reject(x); });
return self;
}
"undefined" !== typeof module && (module.exports = Promise) || (window["Promise"] = Promise);
})();
(function(){"use strict";function P(q){function l(a,b,c,d){f=m(f,a,c,d),g=m(g,b,c,d)}function g(a){n(1,a)}function f(a){n(0,a)}function p(a,b,c,d,e){try{e=a(b),e&&h(e.then)?e.then(c,d):c(e)}catch(e){d(e)}}function m(a,b,c,d){return function(e){a(e),p(b,e,c,d)}}function n(a,b){f=g=function(){},l=function(c,d,e,f){j.push(function(){p([c,d][a],b,e,f)}),setTimeout(function(){while(j.length)j.shift()()},0)}}function h(a){return"function"===typeof a}var j=[],k=this||{};k.then=function(a,b){return new P(function(c,d){l(h(a)?a:function(a){return a},h(b)?b:function(b){throw b},c,d)})},q.call(k,function(a){f(a)},function(a){g(a)});return k}"undefined"!==typeof module&&(module.exports=P)||(window.Promise=P)})()
// Adapter for Promises/A+ Compliance Test Suite
var Promise = require("./promise.js")
module.exports = {
pending: function() {
var f, r, p = new Promise(function(fulfill, reject) {
f = fulfill;
r = reject;
});
return {
promise: p,
fulfill: f,
reject: r
};
},
fulfilled: function(value) {
return new Promise(function(fulfill, reject) {
fulfill(value);
});
},
rejected: function(reason) {
return new Promise(function(fulfill, reject) {
reject(reason);
});
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment