mysql / node.js如何使/假同步?

时间:2013-11-06 19:03:30

标签: javascript mysql node.js

我的问题如下:

我在Node中有很多Mysql请求,它是异步完成的。

在下面的示例中,我想在函数doStuffWithInput启动之前等待checkExists函数以某种方式完成(并填充我的输入变量)。我没有看到除了在各种可能的回调中多次粘贴doStuffWithInput之外的任何其他方式(在每个'input = keys;'之后)......我确信有更好的方法。有什么想法吗?

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

完成所有这些后,我们有很多事情要做(产生子进程,更多数据库操作等等)。

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

我真的希望这很清楚,如果需要,我会澄清。

修改

尝试使用promises重写似乎是最好的方法,我想这对于像我这样与厄运金字塔斗争的其他人来说可能是一个很好的例子。 到目前为止,我有:

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

这很神奇!!

2 个答案:

答案 0 :(得分:2)

您可以使用promises而不是回调。节点有很多可能性,你使用的mysql库甚至可以支持它们。例如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;
}

然后你可以做

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

答案 1 :(得分:2)

您应该考虑使用async库。

对于您的情况,您可能希望使用waterfall模式。这些函数将被串行执行,每个函数的结果作为输入传递给下一个。从这里,您可以检查以前功能的结果等。

您还可以以任何方式组合不同的控制流结构。 (即在瀑布流的一个阶段进行并行操作)