带有Q承诺的NodeJS异步

NodeJS asynchronous with Q promises

本文关键字:NodeJS 异步 承诺 带有      更新时间:2023-09-26

我正在使用Nodejs,我想使用承诺,以便在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"});
    }
});};

所有的console .log都可以正常工作,除非最后一个——detected_beacons——一个,它是第一个显示的,它是空的。

这就是为什么我认为承诺没有发挥作用的原因。我有var q = require('q');在顶部和mongo连接没有返回任何问题。

谢谢你的帮助

首先,一个很棒的关于如何与承诺相处的指南。

好吧,讨厌的人会讨厌,但承诺根本没有错(至少,我希望如此)。

根据'MongoDb for Node'文档,.toArray()返回一个承诺,就像这个库的大多数方法一样。我可以随意按照您的代码进行一些预约:

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

我希望它能帮助你!