sql >> Databasteknik >  >> NoSQL >> MongoDB

Hanterar asynkrona databasfrågor i node.js och mongodb

Innan jag förklarar ytterligare, vill jag notera att det finns en bugg i din kod:

function(err_positive, result_positive) {
    result_positive.count(function(err, count){
        console.log("Total matches: " + count);
        positives[i] = count;  // <--- BUG: i id always 5 because it
    });                        //           is captured in a closure
}

Klassiska stängningar &öglor problem. Se:Vänligen förklara användningen av JavaScript-stängningar i loopar

Nu, hur man hanterar asynkrona funktioner i loopar. Grundidén är att du måste hålla reda på hur många asynkrona samtal som har slutförts och köra din kod när det sista samtalet kommer tillbaka. Till exempel:

var END=5;
var counter=end;
for (var i=0;i<END; i++) {
  collection.find(
    {value:1},
    {created_on: 
      {       
        $gte:startTime + (i*60*1000 - 30*1000),
        $lt: startTime + (i*60*1000 + 30*1000)
      }
    },
    (function(j){
      return function(err_positive, result_positive) {
        result_positive.count(function(err, count){
            console.log("Total matches: " + count);
            positives[j] = count;
        });

        counter--;
        if (!counter) {
          /*
           * Last result, now we have all positives.
           *
           * Add code that need to process the result here.
           *
           */
        }
      }
    })(i)
  ); 
}

Men om vi fortsätter att göra detta är det uppenbart att vi kommer att skapa ett gäng temporära variabler och sluta med fruktansvärt kapslad kod. Men eftersom det är javascript kan vi kapsla in logiken för detta mönster i en funktion. Här är min implementering av denna "vänta-på-alla-att-slutföra"-logik i javascript:Koordinera parallell exekvering i node.js

Men eftersom vi använder node.js kan vi använda den bekväma asyncmodulformen npm:https://npmjs .org/package/async

Med async kan du skriva din kod så här:

var queries = [];

// Build up queries:
for (var i=0;i <5; i++) {
  queries.push((function(j){
    return function(callback) {
      collection.find(
        {value:1},
        {created_on: 
          {       
            $gte:startTime + (j*60*1000 - 30*1000),
            $lt: startTime + (j*60*1000 + 30*1000)
          }
        },
        function(err_positive, result_positive) {
          result_positive.count(function(err, count){
            console.log("Total matches: " + count);
            positives[j] = count;          
            callback();
          });
        }

      );
    }
  })(i));
  queries.push((function(j){
    return function(callback) {
      collection.find(
        {value:0},
        {created_on: 
          {
            $gte:startTime + (j*60*1000 - 30*1000),
            $lt: startTime + (j*60*1000 + 30*1000)
          }
        },
        function(err_negative, result_negative) {
          result_negative.count(function(err, count){
            console.log("Total matches: " + count);
            negatives[j] = count;
            callback();
          });
        }   
      );
    }
  })(i));  
}

// Now execute the queries:
async.parallel(queries, function(){
  // This function executes after all the queries have returned
  // So we have access to the completed positives and negatives:

  // For example, we can dump the arrays in Firebug:
  console.log(positives,negatives);
});



  1. Kan jag konfigurera MongoDB för att vara i minnet?

  2. Redis - Använder CONFIG SET i farten i en masterslav-relation

  3. Grundläggande mellan datumfrågor $gte, $lte, etc

  4. Hur man importerar data till mongoDB