xShirase
xShirase

Reputation: 12389

mysql/node.js how to make/fake synchronous?

My problem is as follows :

I have many Mysql requests to do in Node, and it's done asynchronously.

In the following example, I would like to wait for the checkExists function to finish one way or another (and populate my input variable) before the function doStuffWithInput starts. I don't see any other way than pasting doStuffWithInput multiple times in the various possible callbacks (after each 'input=keys;') ... I'm sure there is a better way though. Any ideas?

var input;

db.checkExists_weekParents(id,function(count){ //check table existence/number of rows
    if(count!==='err'){ //if doesnt exist, create table
        db.create_weekParents(id,function(info){ 
            if(info!=='err'){ //as table is empty, create input from a full dataset
                db.makeFull_weekParents(id,function(keys){
                    input = keys;       
                });
            }
        });
    }else{ //if exists, check number of entries and create input keys as a subset of the full dataset
        db.makeDiff_weekParents(id,function(keys){
            if(keys.length!==0){
                input = keys;
            }else{ //if the table already has full dataset, we need to export and start again.
                db.export_weekParents(id,function(info){
                    db.create_weekParents(id,function(info){
                        if(info!=='err'){
                            db.makeFull_weekParents(id,function(keys){
                                input = keys;       
                            });
                        }
                    });
                });
            }
        });
    }
});

Once all this is done, we have lots of stuff to do (spawn child processes, more db operations, etc...)

doStuffWithInput(input,function(output){
    //Tons of stuff here
    console.log(output);
})

I really hope this is clear enough, I'll clarify if needed.

EDIT

Trying to rewrite using promises seems the best way to go, and I imagine it can be a great example for others like me struggling with pyramid of doom. So far I have :

    var Q = require('q');   
    function getInput(){
        var dfd = Q.defer();
        db.check_weekParents(id,function(count){
            console.log('count '+count);
            if(count==='err'){
                db.create_weekParents(id,function(info){
                    if(info!=='err'){
                        console.log('created table');
                        db.makeDiff_weekParents(id,function(keys){
                            input = keys;
                            dfd.resolve(input);
                        });
                    }
                });
            }else{
                db.makeDiff_weekParents(id,function(keys){
                    input=keys;
                    dfd.resolve(input);
                });
            }
        });
        return dfd.promise;
    }
    getInput().then(function (input) {
        console.log(input);
    });

It is magic!!

Upvotes: 2

Views: 1122

Answers (2)

Explosion Pills
Explosion Pills

Reputation: 191819

You can use promises rather than callbacks. There are many possibilities in node, and the mysql library you are using may even support them. For example with Q:

function getInput(){
    var dfd = Q.defer();
    if(count!==='err'){
        db.create_weekParents(id,function(info){
            /* after everything completes */
            dfd.resolve(input);

/* snip */

    return dfd.promise;
}

Then you can do

getInput().then(function (input) {
    doStuffWithInput(input ...
});

Upvotes: 2

Nick Mitchinson
Nick Mitchinson

Reputation: 5480

You should look into using the async library.

For your case you may want to look at using the waterfall pattern. The functions will be executed in series, with the result of each being passed as input to the next. From here, you can check the results of previous functions, etc.

You are also able to combine the different control flow structures in any way you want. (ie, parallel operations at one stage of a waterfall flow)

Upvotes: 2

Related Questions