Skip to content

Instantly share code, notes, and snippets.

@mbarkhau
Created January 14, 2012 23:16
Show Gist options
  • Save mbarkhau/1613315 to your computer and use it in GitHub Desktop.
Save mbarkhau/1613315 to your computer and use it in GitHub Desktop.
Minimalist defer() function
// Adapted mostly from https://github.com/unscriptable/promises/blob/master/src/Tiny.js
// There are a few major problems with this promise that keep it from
// being useful outside of a constrained environment:
// 1. It modifies it's own public API:
// The then(), resolve(), and reject() methods are rewritten when the promise
// is completed (i.e. resolved or rejected). There's nothing inherently wrong
// with this unless some other code is overriding or hijacking the public
// methods (in which case, they'd be overriding the obsolete methods).
// 2. It doesn't distinguish between the "front end" API and the "back end" API:
// If some other code decided to call our reject() method, it could. We would
// typically want to hide our back end API from outside code.
// But if you're looking for the tiniest implementation of a promise, this is
// about as small as you're going to get (minifies to ca 350 bytes).
function defer() {
var thens = [];
function complete(promise, which, arg) {
// switch over to sync then()
promise.then = function (resolve, reject) {
if (which) {
reject && reject(arg);
} else {
resolve && resolve(arg);
}
return this;
}
// disallow multiple calls to resolve or reject
promise.resolve = promise.reject = function () {
throw new Error('Already completed.');
};
// complete all waiting (async) then()s
var aThen, i = 0;
while (aThen = thens[i++]) {
aThen[which] && aThen[which](arg);
}
thens = null;
}
return {
then: function (onResolve, onReject) {
thens.push([onResolve, onReject]);
return this;
},
resolve: function (val) { complete(this, 0, val); },
reject: function (ex) { complete(this, 1, ex); }
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment