简体   繁体   English

NodeJS与Q Promise异步

[英]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. 我正在使用Node.js,并且我想使用Promise,以便在for循环后做出完整的响应。

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. 除非最后一个--- detected_beacons ---一个要显示的第一个并且为空,否则所有consoles.log都可以正常工作。

That is the reason why i'm thinking that the promises are not working well. 这就是为什么我认为承诺不能很好地执行的原因。 I have var q = require('q'); 我有var q = require('q'); at the top and the mongo connection does not return any problem. 在顶部,mongo连接不会返回任何问题。

Thanks for the help. 谢谢您的帮助。

First of all, an awesome guide about how to get along with Promises. 首先,关于如何与Promises相处的很棒的指南

Well, haters gonna hate but there is nothing wrong with Promises at all (at least, I hope so). 好吧,仇恨者会讨厌,但Promises并没有错(至少,我希望如此)。

According to 'MongoDb for Node' documentation , .toArray() returns a Promise, like most of the methods of this library. 根据“ MongoDb for Node”文档.toArray()返回Promise,就像该库的大多数方法一样。 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! 希望对您有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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