【问题标题】:For loop in async function and timing issue异步函数中的 for 循环和计时问题
【发布时间】:2015-03-25 16:57:42
【问题描述】:

我正在向我的 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 
});

});

【问题讨论】:

  • 尝试在异步回调中使用 for 循环索引。这有数百个重复。我看看能不能找到。
  • 看了那篇帖子后,我有点理解这个问题。这里我有两个异步函数,所以usersFriends数据需要经过两个异步函数。我对闭包知之甚少,所以我很困惑。我更新了代码以使用引用帖子中的 for 循环解决方案。
  • 我重新打开了它。这确实解决了for 循环索引的第一个问题。但是,您似乎还有其他问题,因为您需要知道所有内部 .findOne() 操作何时完成,以便您可以知道何时使用 userFriends 结果。这部分也有很多重复。
  • 非常感谢!这就是问题是的,一旦异步函数完成,我需要将 usersFriends 数据传回外部到 usersFriends 数组,以便它可以与块一起发送。
  • 而且仅供参考,这不是范围问题。这是一个时间问题。异步操作在未来某个时间完成。在任何异步响应完成之前,您正在执行console.log(userFriends)

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


【解决方案1】:

将我们在 cmets 中讨论过的所有内容结合起来,形成这个变化列表:

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

                    }
                }
            });
        }
    });
});     

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 2019-04-07
    • 2011-02-16
    • 2020-04-20
    • 2018-09-24
    • 1970-01-01
    相关资源
    最近更新 更多