2016-11-23 3 views
0

私は.each()ループと、各ループで更新されるグローバル変数を持っています。各ループにはcollection.findがあり、node.jsは検索が終了するのを待たずに次の要素に進みます。findが最初の結果を得ても問題はありません。私はそれを待つことが正しいことだとは思わない、私はそれを "ノードの方法"に対処したい(私はしないでください)教えてくださいmongodb cursor.eachでlongsアクションを処理する方法は?

ここに私のコードの簡略化されたバージョンです:

(それはちょうど50歳にしているすべてのクライアントを見つけて、自分たちの街中の店で何かをするだろう)

var clients = db.collection('clients'); 
var current; 
var clientnumber=0; 

clients.find({"age":50},function(err,results){ 
    results.each(function(err,client){ 
     if(client){ 
      clientnumber++; 
      var city = client.city; 
      shops.find({"_id":city},function(err,resCursor){ 
       resCursor.toArray(function(err,bson){ 
        //does stuff using the city, client number variables and data from "shop" 
        //including another find and each operation 
       }); 
      }); 
      clientnumber++; 
     } 
    } 
}); 

clientnumberはIDではありません、それはただそこにどのように多くの50歳のクライアントをカウントare)

このコードを実行すると、eachループがfindでは高速すぎるため、findコールバックが呼び出されると、clientnumbercityなどの変数は最新ではありません。私はここで何をすべきですか?

cities[clientnumber]=cityのような都市の配列を持っていると思っていましたが、どのようにしてclientnumerを追跡するのか分かりません。私はvar currentcity=city;のように変数をローカルに渡すことを考えましたが、次のクライアントに行く前に完了することは確実ではありません。それぞれの入れ子にする必要はありません。

グローバル変数の追跡方法を教えてください。あなたは構造にコメントすることができますが、非常に単純化されているので適用できないかもしれません。

答えて

0

クライアントを順にループします。それぞれの終わりを待ってから次のものを始める。

clients.find({"age":50},function(err,results){ 
    doclient(clientnumber, 0, results.length, results, function(result){ 
     // alldone, clientnumber in result 
    }) 
}) 


function doclient(clientnumber, done, todo, results, callback) 
{ 
    if(done >= todo) 
    { 
     return callback(clientnumber); 
    } 
    else 
    { 
     var client = results[done]; 
     if(client){ 
      clientnumber++; 
      var city = client.city; 
      shops.find({"_id":city},function(err,resCursor){ 
       resCursor.toArray(function(err,bson){ 
        //does stuff using the city, client number variables and data from "shop" 
        //including another find and each operation 

        // call next client 
        setImmediate(doclient, clientnumber, ++done, todo, results, callback); 
       }); 
      }); 
     } 
     else 
     { 
      // call next client 
      setImmediate(doclient, clientnumber, ++done, todo, results, callback); 
     } 
    } 
} 
関連する問題