用于异步函数中的循环和定时问题



我在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. 在IIFE中传递cntr,以便为每个单独的.findOne()请求唯一地捕获它
  2. 在每个响应中,检查这是否是最后一个响应,这样我们就知道所有结果都已到达
  3. Transaction.find()操作完成开始.findOne()操作(由于我不知道该操作,我猜测这个特定方面应该如何实现,但您应该能够看到总体想法)

尽管会导致这个代码:

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

最新更新