javascript - Problema al devolver los datos recuperados de las consultas de DB llamadas en el bucle
node.js mongodb (1)
Comencemos con la regla general para usar promesas:
Cada función que hace algo asíncrono debe devolver una promesa
¿Qué funciones son estas en tu caso?
Es
getPrayerInCat
, la
forEach
llamada
Prayer.find
y
Prayer.find
.
Hm,
Prayer.find
no devuelve una promesa, y es una función de biblioteca, por lo que no podemos modificarla.
La regla 2 entra en juego:
Cree un contenedor inmediato para cada función que no
En nuestro caso, eso es fácil con los ayudantes de interfaz de nodo de Q :
var find = Q.nbind(Prayer.find, Prayer);
Ahora solo tenemos promesas y no necesitamos más aplazamientos. La tercera regla entra en juego:
Todo lo que hace algo con un resultado asíncrono entra en una devolución de llamada
.then
... y devuelve el resultado. ¡Demonios, ese resultado puede ser incluso una promesa si "algo" fuera asíncrono! Con esto, podemos escribir la función de devolución de llamada completa:
function getPrayerCount(data2) {
var id = data2.id;
return find({prayerCat:id})
// ^^^^^^ Rule 1
.then(function(prayer) {
// ^^^^^ Rule 3
if (!prayer)
data2.prayersCount = 0;
else
data2.prayersCount = prayer.length;
return data2;
// ^^^^^^ Rule 3b
});
}
Ahora, tenemos algo un poco más complicado: un bucle.
getPrayerCount()
repetidamente a
getPrayerCount()
nos dará múltiples promesas, cuyas tareas asincrónicas se ejecutan en paralelo y se resuelven en un orden desconocido.
Queremos esperar a todos ellos, es decir, obtener una promesa que se resuelva con todos los resultados cuando haya finalizado cada una de las tareas.
Para tareas tan complicadas, no intente encontrar su propia solución:
Verifique la API de su biblioteca
Y allí encontramos
Q.all
, que hace exactamente esto.
Escribir
getPrayerInCat
es muy fácil ahora:
function getPrayerInCat(data) {
var promises = data.map(getPrayerCount); // don''t use forEach, we get something back
return Q.all(promises);
// ^^^^^^ Rule 1
}
Si necesitáramos hacer algo con la matriz que
Q.all
resuelve, simplemente aplique la Regla 3.
Realizo múltiples consultas mongoDB en bucle. y quiero enviar todos los resultados como una matriz de datos. Pero cuando simplemente uso la devolución para enviar los datos, simplemente devuelve indefinido y no espero los resultados de todas las solicitudes de DB. También intenté usar q.moulde pero el mismo problema.
Código:
var getPrayerInCat = function(data){
var result ;
var finalData = [];
if(data.length >0){
data.forEach(function(data2){
var id= data2.id;
Prayer.find({prayerCat:id},function(err,prayer){
var deferred = Q.defer()
if (err) { // ...
console.log(''An error has occurred'');
// res.send(err);
result= finalData = err
} else {
if(!prayer){
// console.log(data2.id+''--0'');
data2.prayersCount = 0;
result = deferred.resolve(finalData.push(data2))
} else {
// console.log(data2.id+''--''+prayer.length);
data2.prayersCount = prayer.length;
// console.log(prayer)
result = deferred.resolve(finalData.push(data2))
} // else for data forward
}
deferred.promise;
})
// deferred.resolve(finalData);
})
/*if(finalData.length > 0) { return finalData;}*/
}
}
finalData se devuelve indefinido.