当函数陷入循环时,似乎循环的一半不会执行

时间:2018-01-10 09:27:11

标签: javascript asynchronous mongoose

我今天正在为一个关于流动民主的项目的循环函数而苦苦挣扎。在委派投票时,我有一个循环来检查没有忘记任何代表团,这个算法有一个有趣的行为:

Vote.count({
  propId: propId,
  delegation: true
}, function(err, voteNumber) {
  var maxDelegation = voteNumber;
  for (var d = 1; d < maxDelegation + 1; d++) {
    var delegationsLeft = 1; //Is calculated to see if someone delegates to a delegate
    while (delegationsLeft > 0) {
      console.log("I am about to find the votes for " + d + " weight, " + delegationsLeft + " delegation left at least.");
      Vote.find({
        propId: propId,
        delegation: true,
        weight: d
      }, function(err, specWeightVotes) {
        console.log("I'm in.");
        delegationsLeft = specWeightVotes.length;
        for (var i = 0; i < specWeightVotes.length; i++) {
          // Add the weight d, aka the weight of a vote to the delegated voter
          Vote.findOneAndUpdate({
            propId: propId,
            voter: specWeightVotes[i].content
          }, {
            $inc: {
              'weight': specWeightVotes[i].weight
            }
          }, function(err) {
            if (err) {
              console.log("Ca bug.");
            }

            //Put weight as zero for the ones who have delegated
            Vote.findOneAndUpdate({
              _id: specWeightVotes[i]._id
            }, {
              $set: {
                'weight': 0
              }
            }, function(err) {
              if (err) {
                console.log("Ca bug 2.");
              }
            });

          });

        }
      });

    }
  }
  console.log("I have delegated all votes");
});

现在有趣的是,我的while循环永远停留,因为它永远不会执行代码的Vote.find({propId: propId, delegation: true, weight: d}, function(err, specWeightVotes){部分。

如果我查看控制台,我有以下输出:

I am about to find the votes for 1 weight, 1 delegation left at least.
I am about to find the votes for 1 weight, 1 delegation left at least.
I am about to find the votes for 1 weight, 1 delegation left at least.
I am about to find the votes for 1 weight, 1 delegation left at least.
I am about to find the votes for 1 weight, 1 delegation left at least.

...直到最后这个过程耗尽电池。我永远不会看到“我在”的一部分。

我想这可以通过一些更多的异步编程来解决吗?但是,考虑到我的功能甚至没有执行一次,我不确定。

PS:重要提示,在包含此while循环以防止委托被遗忘之前,该算法正在运行。

1 个答案:

答案 0 :(得分:1)

据推测,Vote.find的工作异步(对于Vote.findOneAndUpdate也是如此)。您的forwhile循环没有。所以delegationsLeft在循环过程中永远不会是1。

如果您要与异步结果进行互动,则无法使用while(或fordo-while)。相反,您需要在异步回调中安排“循环”的下一次“迭代”。

(或者将所有代码放入ES2017 + async函数中,将Vote.find包装在返回Promises的包装器中,并使用await。但这需要一个尖端的JavaScript要运行的环境,或使用Babel之类的内容进行转换。)