0

async を使用して node.js を順番に動作させたいと思います。最初に mongodb から 2 つのレートをクエリし、次にこれらのレートを使用して 2 つの新しいレートを計算します。

async.series([
    function(callback){
        db.collection('heros',function(err,collection){
            if(err){
                console.log(err);
            }
            if(!err){
                console.log("2 collection fetched!");
                collection.findOne({'id':win},function(err,result){
                    if (err) throw err;
                    rate1=result.rate;
                    console.log("win-rate:"+rate1);
                });
                collection.findOne({'id':lose},function(err,result){
                    if (err) throw err;
                    rate2=result.rate;
                    console.log("lose-rate:"+rate2);
                });         
            }
        });
        callback(null);

    }, function(callback){   
        var Ea= 1/(1+Math.pow(10,(rate2-rate1)/400));
        var Eb= 1/(1+Math.pow(10,(rate1-rate2)/400));
        var ra= rate1+16*(1-Ea);
        var rb= rate2+16*(0-Eb);
        console.log("ra:"+ra);
        console.log("rb:"+rb);
        callback(null);
    },
        function(callback){   
    db.collection('heros',function(err,collection){
        if(!err){
        collection.update({'id':win},{$set:    {rate:ra}},function(err,result){
          if(err) throw err;
          if(!err){
            console.log("update successful");
          }
          });
          collection.update({'id':lose},{$set:{rate:rb}},function(err,result){
          if(err) throw err;
          if(!err){
            console.log("update successful");
        }
        });

            }

    });
    callback(null);
}
]);

しかし、実行するとエラーメッセージが表示されます:

ReferenceError: ra が定義されていません

nodejs は、クエリの完了を待たずにコンピューティングまたは更新にジャンプするようです。

4

1 に答える 1

5

ra関数ブロック内のように変数を宣言しているため、それらはその関数にスコープされ、他の場所では使用できません。よりアクセスしやすい場所に配置する必要があります。たとえば、それらをグローバル変数に入れることができます。

var ra;

async.series([ ... ]);

さらに、シリーズを使用する場合はcallback、そのステップのすべての作業が完了したときにのみ関数を呼び出す必要があります。

たとえば、1 つのタスクは次のようになります。

db.collection('heros',function(err,collection){
        if(err){
            console.log(err);  // log the error
            callback(err);     // call the async call back with the error
            return;            // stop 
        }
        console.log("2 collection fetched!");
        collection.findOne({'id':win},function(err,result){
            if (err) { callback(err); return; } // again, handle error
            rate1 = result.rate;                // grab results
            console.log("win-rate:"+rate1);     // log
            callback(null, rate1);              // now indicate complete by calling
        });
    });

1 つのタスク内に複数の非同期関数呼び出しがあるため、それらを複数のタスクに分割するか、parallel関数の使用も検討することができます。2 つの呼び出しを行う必要がある場合を処理するためparallelに、呼び出しの他のタスクの 1 つの中で使用することもできます。seriesfindOne

于 2013-08-28T01:19:57.517 に答える