2014-04-01 11 views
11

Verwenden von Mungo, um Ergebnisse aus der db und Q für Versprechungen abzufragen, aber finden es schwer, meinen Kopf herumzuwickeln, nur um eine Liste der verfügbaren Benutzer zu erhalten. Zur Zeit habe ich einige etwas wie folgt aus:Mungo und Versprechen: Wie bekomme ich eine Reihe von Abfrageergebnissen?

var checkForPerson = function(person) { 
    people = mongoose.model('Person', Person) 

    return people.findOne({"_id": person }, function(err, doc) { 
     if (err) console.log(err) 

     if (doc !== null) { 
      return doc 
     } else { 
      console.log('no results') 
     } 

    }) 
} 

var promises = someArrayOfIds.map(checkForPerson); 

// this is where I would like to have an array of models 
var users = Q.all(promises) 

//this fires off before the people.findOne query above to users is undefined 
SomeOtherFunction(users) 

Wie würde ich darüber, dass die Abfragen gehen beenden, bevor SomeOtherFunction ohne Tonnen schlampig Rückrufe zu tun?

Antwort

18

Ein anderer Vorschlag wäre, MongoDB's $in-Operator zu verwenden, um ein Array an find übergeben und eine große Menge von Ergebnissen effizient zu erhalten. Jeder wird ein Mungo-Objekt sein.

var promise = people.find({ _id: { $in: someArrayOfIds }).exec(); 
promise.then(function(arrayOfPeople) { 
    // array of people ... do what you want here... 
}); 

weit effizienter als mehrere Anforderungen zu machen für jede _id, ein Dies würde.

+1

Ich wusste nie, $ In ', ich werde es definitiv versuchen! –

+1

@delboud op, wenn dies die Antwort ist, die Ihr Problem gelöst hat, sollten Sie es in Betracht ziehen, es zu akzeptieren, was Sie gerade akzeptiert haben. In aller Ehrlichkeit, während meine Antwort viel mehr theoretischen Hintergrund und nützliche Informationen über Versprechen IMO gibt - das ist die praktische Antwort für Menschen, die dieses Problem in Mongoose. Sie können meine Antwort verbessern, wenn Sie es nützlich finden, aber ich bin für die praktische Lösung :) –

+1

Ich kämpfte tatsächlich mit Versprechungen, so dass Ihre meine Frage beantwortet, aber er gab mir Einblick in eine Funktion. So oder so mit mir :) –

5

Die Antwort auf die Frage "Wie mache ich weiter mit Versprechungen" ist fast immer mit .then. Es ist die Versprechensanalogie von ; und es beendet eine asynchrone Aussage. Sie können Versprechungen darin zurückgeben und es wird sie auspacken, bevor Sie fortfahren.

Q.all(promises).then(function(users){ 
    SomeOtherFunction(users); 
}); 

Oder einfach Q.all(promise).then(SomeOtherFunction)

Sie müssen auch FindOne tatsächlich Versprechen zurück. Sie können entweder Q.nfcall verwenden, das eine Knotenfunktion aufruft, oder promisify it yourself.

Was Q.all tut ist ein Array von Versprechen und erfüllt, wenn alle von ihnen tun und ablehnt, wenn einer von ihnen ablehnt. Sie könnten einen Handler .catch anhängen, falls eine der Abfragen fehlschlägt, oder .done verwenden, um das Ende einer Kette anzuzeigen. Andere Versprechen Bibliotheken wie Bluebird wird Fehler für Sie auch ohne .done oder Hinzufügen eines expliziten Handler übernehmen, leider tut Q dies nicht.

+4

FYI:. 'FindOne() exec()' gibt ein Versprechen. – WiredPrairie

+2

@WiredPrairie in diesem Fall - OP sollte definitiv 'findOne (..) .exec' verwenden, anstatt sich mit nfcall zu beschäftigen oder es manuell zu promitifizieren. OP - beachte auch, dass du nicht all das '.if (err)' Zeug brauchst, Versprechungen kümmern dich darum. –

4

Sie könnten auch q verwenden (NPM q installieren)

var q = require('q') 
, aPromise = mongooseModelA.find({_id: aId}).exec() 
, bPromise = mongooseModelB.find({_id: bId}).exec(); 

q.all([aPromise, bPromise]).then(function(bothA_and_B) { 
    console.log(bothA_and_B); 
}); 
Verwandte Themen