用于异步功能和定时问题的循环

时间:2015-03-25 16:57:42

标签: javascript node.js mongodb for-loop mongoose

我正在向我的mongodb查询正在通过会话传递的用户电子邮件。找到该电子邮件后,它会查找该用户的朋友,并将这些朋友假设传递给usersFriends数组,然后将该数组发送到浏览器中。我包括了这个块中的所有代码,即使事务块不是真正相关或我认为。

问题:usersFriends数组在任何地方输出一个空数组,除非console.logfor循环内。思考?

app.get('/api/chunk', function(req, res){

var last5;
var usersFriends = [];

Transaction.find().sort({$natural:-1}).limit(5).exec(function(err, docs){
    if (err) {
        console.log(err);
    } else {
        last5 = docs;           
    }
});

User.findOne({ email: req.user.email }, function(err, user){
    if (!user) {
        console.log(err);
    } else {
        for (var i = 0; i < user.friends.length; i++) {
            (function(cntr){
            User.findOne({ email: user.friends[cntr].email}, function(err, result) {
                result.password = "Sneaky sneaky"
                var name = result.firstName + " " + result.lastName;                    
                usersFriends.push({
                    name: name,
                    index: cntr
                });
            });                 
            })(i);

            var chunk = {
                "friends": usersFriends,
                "transactions": last5
            };
        }       }console.log(usersFriends); // empty array 
});

});

1 个答案:

答案 0 :(得分:0)

结合我们在评论中讨论过的所有变化列表:

  1. 在IIFE中传递cntr,以便为每个单独的.findOne()请求唯一捕获它。
  2. 在每个回复中,检查这是否是最后一次回复,以便我们知道所有结果都已到达。
  3. 从完成.findOne()操作开始Transaction.find()操作(因为我不知道该操作,我猜测应该如何实现这个特定方面,但你应该能够看一般的想法)。
  4. 虽然会导致此代码:

    app.get('/api/chunk', function(req, res) {
    
        var last5;
        var usersFriends = [];
    
        Transaction.find().sort({
            $natural: -1
        }).limit(5).exec(function(err, docs) {
            if (err) {
                console.log(err);
            } else {
                last5 = docs;
                User.findOne({
                    email: req.user.email
                }, function(err, user) {
                    if (!user) {
                        console.log(err);
                    } else {
                        var totalCnt = user.friends.length;
                        for (var i = 0; i < totalCnt; i++) {
                            (function(cntr) {
                                User.findOne({
                                    email: user.friends[cntr].email
                                }, function(err, result) {
                                    result.password = "Sneaky sneaky"
                                    var name = result.firstName + " " + result.lastName;
                                    usersFriends.push({
                                        name: name,
                                        index: cntr
                                    });
                                    if (usersFriends.length === totalCnt) {
                                        // all results are done here
                                        // you can create the final response
                                        var chunk = {
                                            "friends": usersFriends,
                                            "transactions": last5
                                        };
                                    }
                                });
                            })(i);
    
                        }
                    }
                });
            }
        });
    });