Issue in returning data retrieved from DB queries called in the loop

前端 未结 1 851
陌清茗
陌清茗 2020-11-22 09:56

I making multiple mongoDB queries in loop. and want to send the all results as one data array.But when I simple use the return for send the data it simply return undefined

相关标签:
1条回答
  • 2020-11-22 10:52

    Let's start with the general rule for using promises:

    Every function that does something asynchronous must return a promise

    Which functions are these in your case? It's getPrayerInCat, the forEach callback, and Prayer.find.

    Hm, Prayer.find doesn't return a promise, and it's a library function so we cannot modify it. Rule 2 comes into play:

    Create an immediate wrapper for every function that doesn't

    In our case that's easy with Q's node-interfacing helpers:

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

    Now we have only promises around, and do no more need any deferreds. Third rule comes into play:

    Everything that does something with an async result goes into a .then callback

    …and returns the result. Hell, that result can even be a promise if "something" was asynchronous! With this, we can write the complete callback function:

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

    Now, we have something a bit more complicated: a loop. Repeatedly calling getPrayerCount() will get us multiple promises, whose asynchronous tasks run in parallel and resolve in unknown order. We want to wait for all of them - i.e. get a promise that resolves with all results when each of the tasks has finished.

    For such complicated tasks, don't try to come up with your own solution:

    Check the API of your library

    And there we find Q.all, which does exactly this. Writing getPrayerInCat is a breeze now:

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

    If we needed to do anything with the array that Q.all resolves to, just apply Rule 3.

    0 讨论(0)
提交回复
热议问题