34

Jade テンプレートをレンダリングする前に複数の MongoDB クエリを作成しようとしていますが、テンプレートをレンダリングする前にすべての Mongo クエリが完了するまで待機する方法がわかりません。

exports.init = function(req, res){


    var NYLakes = {};
    var NJLakes = {};
    var filterNY = {"State" : "NY"};
    db.collection('lakes').find(filterNY).toArray(function(err, result) {
        if (err) throw err;
        NYLakes = result;
    });

    var filterNJ = {"State" : "NJ"};
    db.collection('lakes').find(filterNJ).toArray(function(err, result) {
        if (err) throw err;
        NJLakes = result;
    });

    res.render('explore/index', {
            NYlakes: NYLakes,
            NJlakes: NJLakes
    });

};
4

5 に答える 5

58

私はアンダースコア/ロダッシュの大ファンなので、通常は を使用します_.after。これは、特定の回数呼び出された後にのみ実行される関数を作成します。

var finished = _.after(2, doRender);

asyncMethod1(data, function(err){
  //...
  finished();
});

asyncMethod2(data, function(err){
  //...
  finished();
})

function doRender(){
  res.render(); // etc
} 

JavaScript は構文で定義された関数の定義を巻き上げるのでfunction funcName()、コードは自然に上から下に読みます。

于 2013-08-02T07:57:04.440 に答える
19

次の操作を開始する前に 1 つの操作が完了するのを待つのではなく、2 つの操作を並行して実行すると仮定すると、各コールバックで完了した操作の数を追跡する必要があります。

生の node.js JavaScript では、これを行う 1 つの方法は次のようになります。

exports.init = function(req, res){
    var NYLakes = null;
    var NJLakes = null;
    var filterNY = {"State" : "NY"};

    db.collection('lakes').find(filterNY).toArray(function(err, result) {
        if (err) throw err;
        NYLakes = result;
        complete();
    });

    var filterNJ = {"State" : "NJ"};
    db.collection('lakes').find(filterNJ).toArray(function(err, result) {
        if (err) throw err;
        NJLakes = result;
        complete();
    });

    function complete() {
        if (NYLakes !== null && NJLakes !== null) {
            res.render('explore/index', {
                NYlakes: NYLakes,
                NJlakes: NJLakes
            });
        }
    }

};

基本的にここで起こっていることは、各操作の最後にすべての操作が終了したかどうかを確認し、その時点で操作を終了することです。

これらのことをたくさん行っている場合は、この種のことを管理しやすくするためのツールの例として、非同期ライブラリを見てください。

于 2013-08-02T04:05:52.097 に答える
6

非同期モジュールを使用できます:

var states = [{"State" : "NY"},{"State" : "NJ"}];

var findLakes = function(state,callback){
  db.collection('lakes').find(state).toArray(callback);
}

async.map(states, findLakes , function(err, results){
    // do something with array of results
});
于 2013-08-02T04:13:50.740 に答える