@lexi.ch home, code, stuff

Javascript Promise implementation 09.08.2013

My own try of a Promise implementation (see http://en.wikipedia.org/wiki/Futures_and_promises) in JavaScript.

Supports:

// -------- 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);
        });
    });
}