7

I have a Node.js application where multiple funcions might be called, depending on several factors, but only one last function is called after the last callback.

This is a simplified version of what I got:

if(foo === bar){
    function1(arg1, function(val1){
        doWhatever(val1, function(){
            res.end("Finished");
        });
    });
}else if(foo === baz){
    function2(arg2, function(val2){ 
        doWhatever(val2, function(){
            res.end("Finished");
        });
    });
}else{
    function3(arg3, function(val3){
        doWhatever(val3, function(){
            res.end("Finished");
        });
    });
}

And this is what im doing:

var finished = false;

if(foo === bar){
    function1(arg1, function(val1){
        result = val1;
        finished = true;
    });
}else if(foo === baz){
    function2(arg2, function(val2){ 
        result = val2;
        finished = true;
    });
}else{
    function3(arg3, function(val3){
        result = val3;
        finished = true;
    });
}

var id = setInterval(function(){
    if(finished === true){
        clearInterval(id);
        doWhatever(result, function(){
            res.end("Finished");
        });
    }
}, 100);

I guess this can be simplified by using promises, however im not sure how should I implement them.

3
  • 1
    I love using asyncjs - github.com/caolan/async Commented Mar 18, 2014 at 16:53
  • You could consider using the excellent async module from github.com/caolan/async Commented Mar 18, 2014 at 16:54
  • async is pretty good, then you can get rid of the setinterval, which is pretty icky. You would just wait for the async callback to finish to do whatever. Another way would be to do the first way you have, and remove the extra function wrapper around 'dowtvr': function1(arg1, dowtvr); should work fine and be prettier. You also wouldn't need the cb in the dowtvr function. Commented Mar 18, 2014 at 17:27

3 Answers 3

8

You could also do it using when and promises, which IMHO is the easiest to read.

var promises = [];

if(x) {
    var deferred1 = when.defer();
    doSomethingAsync({ callback: deferred1.resolve });
    promises.push(deferred1.promise);
} else if(y) {
    var deferred2 = when.defer();
    doSomethingAsync({ callback: deferred2.resolve });
    promises.push(deferred2.promise);
} else if(z) {
    var deferred3 = when.defer();
    doSomethingAsync({ callback: deferred3.resolve });
    promises.push(deferred3.promise);
}

when.all(promises).then(function () {
    console.log('Finished Promises');
});
Sign up to request clarification or add additional context in comments.

2 Comments

Everything works great, except that promises should be pushed to the array: promises.push(deferred1.promise);
Using when is useful in situations where you cannot collect all of the asynchronous function calls into a single location, which seems to be necessary in order to use async.
3

Here's one way with async series.

https://github.com/caolan/async#series

async.series([
    function(callback){
        if(foo === bar){
            function1(arg1, function(val1){
                callback(null, val1);
            });
        }else if(foo === baz){
            function2(arg2, function(val2){ 
                callback(null, val2);
            });
        }else{
            function3(arg3, function(val3){ 
                callback(null, val3);
            });
        }
    }  
], function(error, valArray){
       doWhatever(valArray[0], function(){
           res.end("Finished");
       });
});

Comments

3

Here's using wait.for

https://github.com/luciotato/waitfor

//in a fiber
var result;
if(foo === bar){
    result = wait.for(function1,arg1);
}else if(foo === baz){
    result = wait.for(function2,arg2);
}else{
    result = wait.for(function3,arg3);
};

doWhatever(result, function(){
        res.end("Finished");
});

You need to be in a fiber (or generator) to use wait.for, but, if you have a lot of callback hell, wait.for is a good approach.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.