MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Problème de retour des données récupérées à partir des requêtes DB appelées dans la boucle

Commençons par la règle générale d'utilisation des promesses :

Chaque fonction qui fait quelque chose de manière asynchrone doit renvoyer une promesse

De quelles fonctions s'agit-il dans votre cas ? C'est getPrayerInCat , le forEach rappel et Prayer.find .

Hum, Prayer.find ne renvoie pas de promesse, et c'est une fonction de bibliothèque donc nous ne pouvons pas la modifier. La règle 2 entre en jeu :

Créez un wrapper immédiat pour chaque fonction qui ne le fait pas

Dans notre cas, c'est facile avec les assistants d'interface de nœud de Q :

var find = Q.nbind(Prayer.find, Prayer);

Maintenant nous n'avons plus que des promesses autour, et n'avons plus besoin de report. La troisième règle entre en jeu :

Tout ce qui fait quelque chose avec un résultat asynchrone va dans un .then rappel

… et renvoie le résultat. Enfer, ce résultat peut même être une promesse si "quelque chose" était asynchrone ! Avec cela, nous pouvons écrire la fonction de rappel complète :

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

Maintenant, nous avons quelque chose d'un peu plus compliqué :une boucle. Appel répété de getPrayerCount() nous obtiendra plusieurs promesses, dont les tâches asynchrones s'exécutent en parallèle et se résolvent dans un ordre inconnu. Nous voulons les attendre tous - c'est-à-dire obtenir une promesse qui se résout avec tous les résultats lorsque chacune des tâches est terminée.

Pour des tâches aussi compliquées, n'essayez pas de trouver votre propre solution :

Vérifiez l'API de votre bibliothèque

Et là on trouve Q.all , qui fait exactement cela. Écrire getPrayerInCat est un jeu d'enfant maintenant :

function getPrayerInCat(data) {
    var promises = data.map(getPrayerCount); // don't use forEach, we get something back
    return Q.all(promises);
//  ^^^^^^ Rule 1
}

Si nous devions faire quoi que ce soit avec le tableau que Q.all se résout à, appliquez simplement la règle 3.