【问题标题】:NodeJS asynchronous with Q promisesNodeJS 与 Q Promise 异步
【发布时间】:2017-01-09 05:34:01
【问题描述】:

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

所有的 consoles.log 都可以正常工作,除非最后一个 ---detected_beacons--- 一个,这是第一个要显示的并且它是空的。

这就是为什么我认为承诺效果不佳的原因。我有 var q = require('q');在顶部,mongo 连接不会返回任何问题。

感谢您的帮助。

【问题讨论】:

  • 因为promises 数组是异步填充的。
  • 我该如何解决?
  • promises.push(defer.promise); 放在异步回调之外?顺便说一句,你也得到了common closure in a loop problem。最好将promsificationfind 分解为单独的函数。
  • @Bergi 你是对的!在循环中重用 Promise 是一种反模式。
  • 我明白你们在说什么,但我无法修复错误。我已经多次更改代码,但发送的第一件事是空数组

标签: javascript node.js mongodb promise q


【解决方案1】:

首先,一个awesome guide 关于如何与 Promises 相处。

好吧,讨厌的人会讨厌,但 Promise 没有任何问题(至少,我希望如此)。

根据'MongoDb for Node' documentation.toArray() 返回一个 Promise,就像这个库的大多数方法一样。我可以根据您的代码随意预约:

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

希望对你有帮助!

【讨论】:

    猜你喜欢
    • 2015-04-15
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-31
    • 2014-04-28
    • 1970-01-01
    • 2014-07-16
    相关资源
    最近更新 更多