javascript - 等到 forEach 循环完成?

标签 javascript node.js async.js

在 forEach 循环之后直接添加回调不起作用。我是 Node.js 新手,因此我们将不胜感激,谢谢。

这适用于记录玩家登录和注销时间的 Minecraft 机器人。在我被服务器踢出后,我想在尝试重新加入之前结束所有玩家 session ,但在下面的代码中,即使我使用 async.series 它仍然不会等到第一个函数完成 -这是由于我的回调位置造成的吗?

bot.on('kicked', function(reason) {
  console.log("I got kicked for", reason, "lol");
  var timestamp = getTimestamp();

    async.series([
      function(callback) {
        console.log("logging out all players");
        logoutAllPlayers(timestamp, function(finished) {
          console.log("logged out all players " + finished);
          if (finished) {
            callback();
          }
        });
      },
      function(callback) { //don't execute until previous function has run completely
        //rejoin here
        bot = mineflayer.createBot(options);
        bindlisteners(bot);
      }
    ]);
});

...

放置回调的正确位置在哪里?

function logoutAllPlayers(timestamp, callback) {
      findOnlinePlayers(function(onlinePlayers) {
          if (onlinePlayers.length > 0) {
              onlinePlayers.forEach(function(player) {
                var playerId = player.id;
                var username = player.username;

                async.waterfall([
                  function(callback) { //add logout event
                    addEvent(playerId, 2, timestamp, function(logoutEventId) {
                      console.log("[" + timestamp + "] " + "Created logout: " + logoutEventId + " for " + username + " (" + playerId +")");
                      callback(null, logoutEventId);
                    });
                  },
                  function(logoutEventId, callback) { //find players current session
                    findSession(playerId, function(sessionId, loginEventId) {
                      console.log("[" + timestamp + "] " + "Found session: " + sessionId +" for " + username + " (" + playerId +")");
                      callback(null, sessionId, loginEventId, logoutEventId); 
                    });
                  },
                  function(sessionId, loginEventId, logoutEventId, callback) { //get timestamps for login and logout events to find the duration of session
                    findEventTimestamp(loginEventId, function(loginTimestamp) {
                      findEventTimestamp(logoutEventId, function(logoutTimestamp) {
                        var difference = diffBetweenTimestamps(loginTimestamp, logoutTimestamp);
                        console.log("[" + timestamp + "] " + "Duration: " + difference + " for " + username);
                        callback(null, sessionId, logoutEventId, difference, callback);
                      }); 
                    });
                  },
                  function(sessionId, logoutEventId, difference, callback) { //end session and update online status
                    endSession(sessionId, logoutEventId, difference, function(callback) {
                      console.log("[" + timestamp + "] " + "Updated session: " + sessionId + " for " + username + " (" + playerId +")");
                      updatenOnlineStatus(playerId, false); 
                    });     
                  }
                ]);
            });
            callback(true);
          }
      });
    }

最佳答案

logoutAllPlayers 中,您正在调用 callback(true); 您的 async.waterfall 调用完成之前它的步骤。

相反,您应该从 //end session and update online status 调用最终的 waterfall callback,然后更改 waterfall 的最后一行以进行完成回调。

async.waterfall([
  // ...
], function(){
  callback(true);
});

关于javascript - 等到 forEach 循环完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20367455/

相关文章:

node.js - Node JS 同步数据库调用

javascript - 如何将数组的键分配为函数的参数?

javascript - 在 html 页面中显示来自 s3(亚马逊)的图像

mysql - Sequelize ORM在选择中添加主键列,而我排除了它

javascript - 如何从 async.js 系列返回结果

javascript - async each 中的异步任务 : Callback to be run after all task and sub tasks completed

javascript - NodeJS 中的流

javascript - Angular.js 单元测试 "inject()"在 "run"阶段 block 之前触发

javascript - 对象分配产生 undefined variable

javascript - AngularJS + 音位间隙 : access to Facebook login/SDK without a server