Last active
December 30, 2015 12:29
-
-
Save jasondscott/7829588 to your computer and use it in GitHub Desktop.
Javascript Deferred implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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