Skip to content

Instantly share code, notes, and snippets.

@ScalableJS
Last active December 12, 2015 10:49
Show Gist options
  • Save ScalableJS/4761680 to your computer and use it in GitHub Desktop.
Save ScalableJS/4761680 to your computer and use it in GitHub Desktop.
The class Deferrer can register multiple callbacks into a callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function.
/*
The class Deferrer can register multiple callbacks into a callback queues,
invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function.
*/
function Deferred() {
var
eventManager = EventManager({once: true,memory: true}),
stateValue = 'pending';
//Interface: presupposes that you can implement basic interface, and extended.
function Promise() {
/**
* Add handlers to be called when the Deferred object is resolved.
* @param fn
* @return {self}
*/
function done(fn) {
eventManager.bind('done',fn);
return this;
}
/**
* Add handlers to be called when the Deferred object is rejected.
* @param fn
* @return {self}
*/
function fail(fn) {
eventManager.bind('fail',fn);
return this;
}
/**
* Add handlers to be called when the Deferred object is either resolved or rejected.
* @param fn
* @return {self}
*/
function always(fn) {
eventManager.bind('done',fn).bind('fail',fn);
return this;
}
/**
* Determines the current state of a Deferred object.
* @return {String}
*/
function state() {
//[resolved | rejected | pending]
return stateValue;
}
return {
done: done,
fail: fail,
always: always,
state: state
}
}
/***
* Merge the contents of two objects together into the first object.
* @param target{Object}
* @param object{Object}
*/
function extend(target,object) {
for (var prop in object) if (object.hasOwnProperty(prop)) {
target[prop] = object[prop]
}
return target;
}
/**
* Resolve a Deferred object and call any doneCallbacks with the given args.
* @param arguments
* @return {self}*/
function resolve() {
if (stateValue === 'pending') {
eventManager.
trigger('done',arguments).
lock('reject');
stateValue = 'resolve';
}
return this;
}
/**
* Reject a Deferred object and call any failCallbacks with the given args.
* @param arguments
* @return {self}
*/
function reject() {
if (stateValue === 'pending') {
eventManager.
trigger('fail',arguments).
lock('resolve');
stateValue = 'reject';
}
return this;
}
var promise = Promise();
return extend({
promise: promise,
resolve: resolve,
reject: reject
},promise)
}
function when() {
var defer = Deferred(),
length = arguments.length,
countDone = length;
function fn() {
if (!--countDone)
defer.resolve()
}
for (var i = 0; i < length; i++) {
arguments[i].done(fn);
}
return defer;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment