Skip to content

Instantly share code, notes, and snippets.

@dtinth
Created December 9, 2012 12:18
Show Gist options
  • Save dtinth/4244628 to your computer and use it in GitHub Desktop.
Save dtinth/4244628 to your computer and use it in GitHub Desktop.
function checkGood(good) { return good; }
function checkBad(good) { return !good; }
function checkAlways(good) { return true; }
function defer() {
var result = null
var finish = false
var good
var handlers = []
function callHandlers() {
if (!handlers) return
for (var i = 0; i < handlers.length; i ++) {
if (handlers[i].check(good)) {
handlers[i].fn.apply(null, result)
}
}
handlers = null
}
function addHandler(callback, check) {
if (finish) {
if (check(good)) callback()
return this
}
handlers.push({ check: check, fn: callback })
return this
}
function handle(status, args) {
if (finish) return
finish = true
good = status
result = Array.prototype.slice.call(args)
callHandlers()
}
return {
resolve: function() {
handle(true, arguments)
},
reject: function() {
handle(false, arguments)
},
done: function(callback) {
addHandler(callback, checkGood)
return this
},
fail: function(callback) {
addHandler(callback, checkBad)
return this
},
always: function(callback) {
addHandler(callback, checkAlways)
return this
},
tap: function(fn) {
fn(this)
return this
},
thru: function(fn) {
var d = defer()
this.fail(d.reject)
this.done(fn(d))
return d
},
pipe: function(fn) {
return this.thru(function(d) {
return function() {
try {
d.resolve(fn.apply(null, arguments))
} catch (e) {
d.reject()
}
}
})
}
}
}
defer.callback = function(o) {
return function(err) {
if (err) {
o.reject(err)
} else {
o.resolve.apply(o, Array.prototype.slice.call(arguments, 1))
}
}
}
module.exports = defer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment