简体   繁体   中英

NodeJS asynchronous with Q promises

I'm working with Nodejs and i want to use promises in order to make a full response after a for loop.

exports.getAlerts = function(req,res,next){
var detected_beacons = [];
if (!req.body  || Object.keys(req.body).length == 0) {
    res.status(401);
    res.json({message:'No data sent'});
    return
}
var nets = req.body.networks;
db.collection("beaconConfig", function(err, beaconConfigCollection){
    if (!err){
        var promises = [];
        for(var i=0;i<nets.length;i++){
            var defer = q.defer();
            beaconConfigCollection.find({$or: [{"data.major" : nets[i].toString()},{"data.major" : nets[i]}], batteryLevel : {$lt : 70}}).toArray(function(errFind, saver){
                if (!errFind && saver && saver.length > 0){
                    promises.push(defer.promise);
                    console.log("--------------------savers -------------------");
                    console.log(saver);
                    for(var j=0; j<saver.length;j++){
                        console.log("--------------------saver[j]-------------------");
                        console.log(saver[j]);
                        var detected = {}
                        var major = saver[j].data.major;
                        detected.major = major;
                        console.log("--------------------detected -------------------");
                        console.log(detected);
                        detected_beacons.push(detected);
                        defer.resolve(detected);
                    }
                }
            });
        }
        q.all(promises).then(function(results){
            console.log("--------------------detected_beacons -------------------");
            console.log(detected_beacons);
            res.json(detected_beacons);
        });

    } else {
        console.error(err);
        res.status(500);
        res.json({message:"Couldn't connect to database"});
    }
});};

All the consoles.log works fine unless the last one, the ---detected_beacons--- one, which is THE FIRST ONE to be shown and it is empty.

That is the reason why i'm thinking that the promises are not working well. I have var q = require('q'); at the top and the mongo connection does not return any problem.

Thanks for the help.

First of all, an awesome guide about how to get along with Promises.

Well, haters gonna hate but there is nothing wrong with Promises at all (at least, I hope so).

According to 'MongoDb for Node' documentation , .toArray() returns a Promise, like most of the methods of this library. I felt free to make some appointments along your code:

exports.getAlerts = function(req, res, next) {
    if (!req.body || Object.keys(req.body).length == 0) {
        res.status(401);
        res.json({message: 'No data sent'});
        return;
    }
    // db.collection returns a promise :)
    return db.collection("beaconConfig").then(function(beaconConfigCollection) {
        // you can use .map() function to put together all promise from .find() 
        var promises = req.body.networks.map(function(net) {
            // .find() also returns a promise. this promise will be concat with all
            // promises from each net element.
            return beaconConfigCollection.find({
                $or: [{
                    "data.major": net.toString()
                }, {
                    "data.major": net
                }],
                batteryLevel: {
                    $lt: 70
                }
            }).toArray().then(function(saver) {
                // you can use the .find() response to create an array
                // with only the data that you want.
                return saver.map(function(saverElement) {
                    // your result array will be composed using saverElement.data.major
                    return saverElement.data.major;
                });
            }).catch(function(err) {});
        });
        // use q.all to create a promise that will be resolved when all promises
        // from the array `promises` were resolved.
        return q.all(promises);
    }).then(function(results) {
        console.log("results", results);
    }).catch(function(err) {});
};

I hope it helps you!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM