2013-12-04 6 views
2

Добавление обратного вызова прямо после того, как цикл forEach не работает. Я новичок в node.js, поэтому любая помощь будет оценена, спасибо.Дождитесь окончания цикла forEach?

Это для ботинка Minecraft, который регистрирует время входа в систему и выхода из системы. После того, как меня ударят с сервера, я хочу закончить все сеансы игроков, прежде чем пытаться воссоединиться, но в следующем коде, даже если im использует 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); 
      } 
     }); 
    } 

ответ

5

В logoutAllPlayers, вы звоните callback(true);, прежде чем вашего async.waterfall вызова закончил свои шаги.

Вместо этого вы должны назвать этот последний водопад callback от //end session and update online status, а затем изменить последнюю линию водопада, чтобы получить обратный вызов завершения.

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

Wow красиво и просто спасибо :) – Jonathan

+0

Я хотел бы предложить добавление поймать ошибки в этой функции, '..], функция (ERR) {обратного вызова (!! ERR); } ', если у вас нет лучшего« ложного »подхода к дальнейшему продвижению. – blakev

Смежные вопросы