2017-01-07 5 views
0

Ich versuche, ein Array mit Datensätzen aus einer MongoDB-Datenbank mit Mungo zu füllen. Wenn ich versuche, die Aufzeichnungen zu füllen. Es zeigt ein leeres Array außerhalb der Funktion, obwohl ich das Äußere der Funktion deklariere. Unten ist der Code.Rückgabe leeres Array in NodeJs mit Mungo

var saveMessageToVariable = function(){ 
    var records = []; 
    var spark_ids = []; 
    var obj = new Object(); 
    Message.find().distinct("spark_id").exec(function(err,data) { 
     data.forEach(function (id) { 
      if(id != null) 
      spark_ids.push(id); 
     }); 
     // console.log(spark_ids.length); 
     spark_ids.forEach(function(spark_id){ 
       Message.findOne({"spark_id":spark_id}).sort({"date":-1}).exec(function(err,data){ 
        obj.spark_id = data.spark_id; 
        obj.meesage = data.message; 
        obj.date = data.date; 
        obj.message_id = data._id; 
        records.push(obj); 
    }); 
     }); 


    }); 

console.log(records); 

} 

Wenn ich dies ausführen, zeigt das Protokoll ein leeres Array. Wie behebe ich dieses Problem?

Antwort

0

Es ist ein asynchroner Aufruf und sobald Daten aus der Datenbank die Steuerung geht zur nächsten Zeile abgerufen wird und daher druckt den Anfangswert, würde ich Sie lieber einen Rückruf wie folgt verwenden:

function(spark_id,callback){ 
       Message.findOne({"spark_id":spark_id}).sort({"date":-1}).exec(function(err,data){ 
        obj.spark_id = data.spark_id; 
        obj.meesage = data.message; 
        obj.date = data.date; 
        obj.message_id = data._id; 
        callback(obj); 

    }); 
} 

function(obj) 
{ 
records.push(obj); 
} 

Sie zwei andere Ansätze hierfür:

1) Verwenden Sie versuchen und fangen Block.

2) async verwenden und Schlüsselwort erwarten.

Prost!

0

Ich habe nicht viel Erfahrung mit Moongoose, aber according to the docs it supports promises since Version 4.

Dann sollte diese Arbeit:

//I assume you'll need this more often 
function notNull(value){ return value != null; } 

//returns a promise of the records-Array 
var saveMessageToVariable = function(){ 

    //returns a promise of a formated message 
    function getMessage(spark_id){ 
     return Message.findOne({ spark_id }) 
      .sort({ date: -1 }) 
      //.exec() 
      .then(formatMessage) 
    } 

    function formatMessage(msg){ 
     return { 
      spark_id: msg.spark_id, 
      message: msg.message, 
      date:  msg.date, 
      message_id: msg._id 
     } 
    } 

    return Message.find() 
     .distinct("spark_id") 
     //.exec() 
     .then(function(ids){ 
      //waits for all findOnes to complete, then returns an Array 
      return Promise.all(
       ids.filter(notNull).map(getMessage) 
      )); 
} 

Ich bin nicht sicher, ob Sie exec() in diesem Code oder nicht benötigen. Du solltest das überprüfen.

//usage 
saveMessageToVariable.then(function(records){ 
    console.log(records); 
}) 

btw. saveMessageToVariable spiegelt überhaupt nicht wider, was diese Funktion macht. Sie sollten einen besseren Namen wählen.