Valor de retorno de la función asíncrona en Nodejs

Estoy usando nodejs para consultar datos de Mongodb a través de Mongoose. Después de obtener los datos, quiero hacer algo con esos datos antes de responderlos al cliente. Pero no puedo obtener el valor de retorno. Después de buscar en Google, he aprendido que las funciones de Node.js son funciones de javascript asíncronas (sin locking de E / S). Intento este tut ( http://www.youtube.com/watch?v=xDW9bK-9pNY ) pero no funciona. A continuación se muestra mi código. El valor de myObject se valora dentro de la función “find ()” y la función externa “find ()” indefinida. Entonces, ¿qué debo hacer para obtener los datos? ¡Gracias!

var Person = mongoose.model('Person', PersonSchema); var Product = mongoose.model('Product', ProductSchema); var myObject = new Object(); Person.find().exec(function (err, docs) { for (var i=0;i<docs.length;i++) { Product.find({ user: docs[i]._id},function (err, pers) { myObject[i] = pers; console.log(myObject[i]); //return the value is ok }); console.log(myObject[i]); //return undefined value } console.log(myObject); //return undefined value }); console.log(myObject); //return undefined value app.listen(3000); console.log('Listening on port 3000'); 

La razón por la que está obteniendo valores no definidos es porque la función de búsqueda es asíncrona y puede finalizar en cualquier momento. En su caso, finaliza después de usar console.log() , por lo que los valores no están definidos cuando se accede a ellos.

Para solucionar este problema, solo puede usar los valores dentro de la callback de la función de búsqueda. Se vería algo como esto:

 var Person = mongoose.model('Person', PersonSchema); var Product = mongoose.model('Product', ProductSchema); var myObject = new Object(); function getData(docs, callback) { function loop(i) { Product.find({ user: docs[i]._id}, function (err, pers) { myObject[i] = pers; if (i < docs.length) { loop(i + 1); } else { callback(); } }); }; loop(0); }; Person.find().exec(function(err, docs) { getData(docs, function() { // myObject has been populated at this point }); }); 

El procesamiento de datos se ha movido a un bucle que espera a que se complete la iteración anterior. De esta manera, podemos determinar cuándo se ha activado la última callback para activar la callback en la función de contenedor.

Tenga en cuenta que para cuando se ejecuten las funciones console.log, la consulta aún no ha finalizado, por lo que se mostrará “indefinido”. Esa es la esencia de la asincronicidad de nodeJS.

Por ejemplo,

 Person.find().exec(function (err, docs) { for (var i=0;i 

Si realmente desea esperar hasta que la consulta haya finalizado para poder usar los valores, recomendaría mover app.listen(3000); y console.log('Listening on port 3000'); en la callback final de la función.

También te recomiendo que revises este módulo de nodo. Le ayudará a crear funciones asíncronas / síncronas con mayor facilidad y le permitirá ejecutar una callback cuando todas las funciones asíncronas hayan finalizado.