sql >> Base de Datos >  >> NoSQL >> MongoDB

Problema al devolver datos recuperados de consultas de base de datos llamadas en el ciclo

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 , el forEach devolución de llamada y Prayer.find .

Hm, Prayer.find no devuelve una promesa y es una función de biblioteca, por lo que no podemos modificarla. Entra en juego la regla 2:

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 ya no necesitamos aplazamientos. Entra en juego la tercera regla:

Todo lo que hace algo con un resultado asíncrono va a un .then devolución de llamada

…y devuelve el resultado. Demonios, ¡ese resultado puede incluso ser 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. Llamar 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, es decir, obtener una promesa que se resuelva con todos los resultados cuando cada una de las tareas haya finalizado.

Para tareas tan complicadas, no intentes encontrar tu propia solución:

Consulta la API de tu biblioteca

Y ahí encontramos Q.all , que hace exactamente esto. Escribiendo getPrayerInCat ahora es pan comido:

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.