2

私の問題は次のとおりです。

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

これが十分に明確であることを本当に願っています。必要に応じて明確にします。

編集

promise を使用して書き直そうとするのが最善の方法のように思われます。これは、私のように破滅のピラミッドに苦しんでいる他の人にとって良い例になると思います。これまでのところ、私は持っています:

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

魔法です!!

4

2 に答える 2

2

非同期ライブラリの使用を検討する必要があります。

あなたのケースでは、ウォーターフォールパターンを使用して見たいと思うかもしれません。関数は順番に実行され、それぞれの結果が入力として次の関数に渡されます。ここから、これまでの機能の結果などを確認できます。

また、さまざまな制御フロー構造を自由に組み合わせることができます。(つまり、ウォーターフォール フローの 1 つのステージでの並列操作)

于 2013-11-06T19:20:05.257 に答える
2

コールバックではなくプロミスを使用できます。ノードには多くの可能性があり、使用している 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 ...
});
于 2013-11-06T19:19:14.030 に答える