Javascript Promise implementation 2013-08-09
My own very naïve implementation / brain dump of a Promise implementation (see http://en.wikipedia.org/wiki/Futures_and_promises) in JavaScript.
Note: This has NOTHING to do with today’s modern Promise implementation. It was a very first try to implement a Promise by myself, within about 30 minutes.
Supports:
- single promise: promise.then()
- multiple (all) promises: Promise.when(p1,p2..).then()
// -------- library things, none of interest -------
Array.each = function(arr,f) {
var i = 0;
for (i = 0; i < arr.length; i++) {
f(arr[i],i);
}
}
function out() {
Array.each(arguments, function(item) {
document.write('<p style="background-color: #3F3;border: 1px solid #008800;">'+item+'</p>');
});
};
// =============== Promise class ==================
var Promise = function() {
this.callback = null;
this.count = 1;
};
Promise.prototype.done = function(err,options) {
if (typeof this.callback === 'function') {
return this.callback(err,options);
}
};
Promise.when = function() {
var i = 0;
var count = 0;
var resp = [];
var p = new Promise();
var act = null;
if (arguments && arguments.length > 0) {
p.count = arguments.length;
count = p.count;
Array.each(arguments,function(item,index) {
item.then(function(err,opts) {
resp[index] = {
err: err,
options: opts
};
count--;
if (count == 0) {
p.done.apply(p,resp);
}
});
});
}
return p;
};
Promise.prototype.then = function(callback) {
this.callback = callback;
};
// ============= END of Promise class ======================
// Example Async task
function doAsync(t) {
var p = new Promise();
setTimeout(function() {
out('async task done after '+t+'ms');
p.done('No Error','Some async things done in '+t+"ms");
},t);
return p;
}
//------------------ Example with single and multiple promises ---------
function go() {
out('Starting async things ...');
var p = doAsync(500).then(function(){
out('single promise execution done.');
});
var p1 = doAsync(1000);
var p2 = doAsync(2000);
Promise.when(p1,p2).then(function(){
out('Multiple promises done ('+this.count+')');
Array.each(arguments,function(item,index){
out('Response #'+index+': '+item.options);
});
});
}