Skip to content

Instantly share code, notes, and snippets.

@jasondscott
Last active December 30, 2015 12:29
Show Gist options
  • Save jasondscott/7829588 to your computer and use it in GitHub Desktop.
Save jasondscott/7829588 to your computer and use it in GitHub Desktop.
Javascript Deferred implementation
function Deferred () {
var rand = Math.random();
var dones = [];
var is_resolved = false;
return {
promise: function () {
},
resolve: function(str) {
while (dones.length > 0) {
var callback = dones.shift();
//callback(str);
callback.call(this, str);
}
is_resolved = true;
},
reject: function() {
},
done: function(callback) {
dones.push(callback);
},
isResolved: function() {
return is_resolved;
}
};
}
function When(/* d1, d2 */) {
var dones = [], //The list of callback we need to call when we are done
deferreds = [], //The list of deferreds we are still waiting to finish
deferreds_copy = [], //A copy of the original deferreds TODO: remove this, it is only being use to return the arguments to done in the correct order
returns = []; //Our list of arguments that we will return when done
for (var i = 0; i < arguments.length; i++) {
if (arguments[i].done) {
deferreds.push(arguments[i]);
deferreds_copy.push(arguments[i]);
arguments[i].done(function(data){
removeDeferred(this, data);
});
}
}
function checkDone() {
if (deferreds.length === 0) {
allDone();
}
}
function removeDeferred(d, data) {
var index = deferreds.indexOf(d);
if (index > -1) {
deferreds.splice(index, 1);
}
index = deferreds_copy.indexOf(d);
if (index > -1) {
returns[index] = data;
}
checkDone();
}
function allDone() {
while (dones.length > 0) {
var callback = dones.shift();
callback.apply(this, returns);
}
}
return {
done: function(callback) {
dones.push(callback);
checkDone();
}
};
}
function getData() {
var deferred = Deferred();
setTimeout(function() {
console.log("timeOOUT");
deferred.resolve("Here is some data");
}, 3000);
return deferred;
}
function getMoreData() {
var deferred = Deferred();
setTimeout(function() {
console.log("timeOOUT Done sooner");
deferred.resolve("Here is more data");
}, 1000);
return deferred;
}
var dataPromise = getData();
dataPromise.done(function(data) {
console.log("dataPromise is done. data: " + data );
});
dataPromise.done(function(data) {
console.log("dataPromise is done and lets have some fun! data: " + data);
});
function getLocation() {
var deferred2 = Deferred();
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(pos){
console.log("We have position");
deferred2.resolve(pos);
});
}
return deferred2;
}
var locationPromise = getLocation();
locationPromise.done(function(data) {
console.log("locationPromise is done - pos.lat: " + data.coords.latitude + " pos.long: " + data.coords.longitude);
});
var allDone = When(dataPromise, locationPromise, getMoreData());
allDone.done(function(a,b,c) {
console.log("We loaded items");
console.log("dataPromise: " + a);
console.log("locationPromise: " + b);
console.log("getMoreData: " + c);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment