tipos - retornar valor de una funcion javascript
Devuelve el valor de la función asÃncrona en Nodejs (2)
La razón por la que obtiene valores indefinidos es porque la función de búsqueda es asincrónica y puede finalizar en cualquier momento. En su caso, está terminando después de usar console.log()
, por lo que los valores no están definidos cuando los está accediendo.
Para solucionar este problema, solo puede usar los valores dentro de la devolución de llamada 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 forma, podemos determinar cuándo se ha activado la última devolución de llamada para activar la devolución de llamada en la función de envoltura.
Estoy usando nodejs para consultar datos de Mongodb a través de Mongoose. Después de obtener la información, quiero hacer algo con esa información antes de responderla 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 una función asíncrona de javascript (sin bloqueo de E / S). Intento este tut ( http://www.youtube.com/watch?v=xDW9bK-9pNY ) pero no es trabajo. A continuación está mi código. El objeto myObject se valora dentro de la función "find ()" y no está definido fuera de la función "find ()". 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'');
Tenga en cuenta que para el momento en que se ejecutan las funciones de console.log, la consulta aún no ha finalizado, por lo que aparecerá "indefinido". Esa es la esencia de la asincronía de nodeJS.
Por ejemplo,
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); // <-- Initially, this value will be undefined. After some miliseconds (Or the duration of the .exec function, myObject will contain the results.
Si realmente desea esperar hasta que la consulta finalice para poder usar los valores, le recomiendo mover la app.listen(3000);
y console.log(''Listening on port 3000'');
en la devolución de llamada final de la función.
También te recomendaría que revises este módulo de nodos. Le ayudará a crear funciones asíncronas / síncronas más fácilmente, y le permitirá ejecutar una devolución de llamada cuando finalicen todas las funciones asíncronas.