Mongoose e promesse: come ottenere una serie di risultati di query?

Usando mangusta per interrogare i risultati di db e Q per le promesse, ma trovando difficile riuscire a capirmi solo ottenendo un elenco di utenti disponibili. Attualmente ho qualcosa di simile a questo:

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 ) 

Come potrei fare per finire le query prima di SomeOtherFunction senza fare tonnellate di callback sciatti?

Un altro suggerimento sarebbe quello di utilizzare l’operatore $in MongoDB per passare in un array per find e ottenere un ampio set di risultati in modo efficiente. Ciascuno sarà un object Mongoose.

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

Questo sarebbe molto più efficiente di fare richieste multiple, una per ogni _id .

La risposta alla domanda “come posso continuare con le promesse” è quasi sempre con. È l’analogia promise di ; e termina un’istruzione asincrona. Puoi restituire le promesse e le scaccherà prima di continuare.

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

O semplicemente Q.all(promise).then(SomeOtherFunction)

Avresti anche bisogno di findOne per restituire effettivamente le promesse. È ansible utilizzare Q.nfcall che chiama una funzione nodo o promette di promuoverlo .

Ciò che Q.all fa è accettare una serie di promesse e si realizza quando tutte le Q.all vengono Q.all quando uno di loro rifiuta. Potresti voler aggiungere un gestore .catch nel caso in cui una delle query fallisca o usi .done per significare la fine di una catena. Altre librerie di promesse come Bluebird raccoglieranno errori anche senza fare o aggiungere un gestore esplicito, purtroppo Q non lo fa.

Puoi anche usare q (npm install q)

 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); });