2016-04-05 27 views
0

所以我一直在用JavaScript编写一个Twitch聊天机器人,并且使用MongoDB来存储关于用户的信息。有一个迷你游戏,在几次“攻击”后,怪物可以被击败,并且用户将在战斗中被授予XP。在当前的战斗中会有一批用户被授予奖励,以及被击败的用户列表。他们仍然获得XP,但他们的“胜利”没有更新。问题是我正在使用for循环执行此操作,直到它更新数组中的每个用户。这种方法很有效,但是却非常麻烦,我认为这是因为函数在数据库有机会赶上之前循环(不确定是否是这种情况,但这是我的假设)。基本上,当数据库试图更新用户时,它有时会多次更新同一个人,而不更新其他人。MongoDB For Loop更新错误的用户

任何想法是什么导致它,如果我的假设听起来是正确的,我该如何避免这种情况?

[Tue, 05 Apr 2016 21:45:25 GMT] INFO: [ARENA] The boss was defeated by 'madmikegamerxl1'. The boss health is: -30 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Game was won, looping to add XP and restore users. Current user: ethelwolv 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Finished updating user 0/8(ethelwolv) 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Game was won, looping to add XP and restore users. Current user: shauncox12345 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Finished updating user 1/8(shauncox12345) 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Game was won, looping to add XP and restore users. Current user: orpheussummanus 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Finished updating user 2/8(orpheussummanus) 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Game was won, looping to add XP and restore users. Current user: acermekz21 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Finished updating user 3/8(acermekz21) 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Game was won, looping to add XP and restore users. Current user: sturgisdanielle 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Finished updating user 4/8(sturgisdanielle) 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Game was won, looping to add XP and restore users. Current user: minnie2292 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Finished updating user 5/8(minnie2292) 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Game was won, looping to add XP and restore users. Current user: epicminer4354 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Finished updating user 6/8(epicminer4354) 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Game was won, looping to add XP and restore users. Current user: madmikegamerxl1 
[Tue, 05 Apr 2016 21:45:25 GMT] INFO: Finished updating user 7/8(madmikegamerxl1) 
[Tue, 05 Apr 2016 21:45:26 GMT] INFO: User 'x0slipknot0x' was not defeated by the boss, incrementing win count 
[Tue, 05 Apr 2016 21:45:28 GMT] INFO: User 'madmikegamerxl1' was not defeated by the boss, incrementing win count 
[Tue, 05 Apr 2016 21:45:28 GMT] INFO: User 'madmikegamerxl1' was not defeated by the boss, incrementing win count 
[Tue, 05 Apr 2016 21:45:28 GMT] INFO: User 'madmikegamerxl1' was not defeated by the boss, incrementing win count 
[Tue, 05 Apr 2016 21:45:28 GMT] INFO: User 'madmikegamerxl1' was not defeated by the boss, incrementing win count 
[Tue, 05 Apr 2016 21:45:28 GMT] INFO: User 'madmikegamerxl1' was not defeated by the boss, incrementing win count 
[Tue, 05 Apr 2016 21:45:28 GMT] INFO: User 'madmikegamerxl1' was not defeated by the boss, incrementing win count 
[Tue, 05 Apr 2016 21:45:28 GMT] INFO: User 'madmikegamerxl1' was not defeated by the boss, incrementing win count 
[Tue, 05 Apr 2016 21:45:28 GMT] INFO: User 'madmikegamerxl1' was not defeated by the boss, incrementing win count 

因此,你可以看到它只是更新一些人。我将发布For循环代码以及更新统计信息的函数之一(我知道我的代码效率不高,可能不必要的长,但我只是确保它现在可以运行):

for (var i = 0; i < arenaConfig.users.length; i++) { // Game was won! Adding XP to every user instead of 1 user. 
    var currentUserI = arenaConfig.users[i]; 

    globalLog("info", "Game was won, looping to add XP and restore users. Current user: " + currentUserI, channel); 

    searchUser(currentUserI, channel.substr(1), function (dataReturned) { 

     if (dataReturned == "new" || dataReturned == "err") { } 
     else { 
      updateUserHealthdb(db, currentUserI, dataReturned.stats.health, function() { 
      setTimeout(function() { 
       // Restored health to user. 
       updateXP(xpToAdd, currentUserI, function() { 
        if (arenaConfig.deadUsers.indexOf(currentUserI) >= 0) { // User was defeated 
         globalLog("info", "User was defeated by the boss, skipping updateWin function. - " + currentUserI, channel); 

        } 
        else { 
         globalLog("info", "User '" + currentUserI + "' was not defeated by the boss, incrementing win count", channel); 
         setTimeout(function() { 
          updateWin(1, currentUserI, function() { 
          }); 

         }, 1000); 
        } 
       }); 
       globalLog("success", "Successfully restored user's health to: " + dataReturned.stats.health, channel); 
      }, 1000); 
     }); 
    } 

}); 


globalLog("info", "Finished updating user " + i + "/" + arenaConfig.users.length + "(" + currentUserI + ")", channel); 


} 

而下面是更新数据库中的统计功能(所有的更新功能有类似的代码,只是调整了不同的数据库字段)

function updateXP(num, user, callback) { 

    dbuser.findOne({ 'name': user }, 'name stats.xp', function (err, person) { 
     if (person != null) { 
      person.stats.xp = person.stats.xp + num; 
      person.save(); 
      globalLog("info", 'update: ' + person.name + ' [' + person.stats.xp + ' ' + "XP" + ' ]'); 
      callback(); 
     } 
    }); 

}; 

任何帮助是极大的赞赏,

Mike

回答

0

您的代码是否曾经进入过这个区块?如果出现错误,您的代码将无提示失败。

if (dataReturned == "new" || dataReturned == "err") { } 

另外,你有一个单一的MongoDB服务器或集群?如果它是聚集的,则读取是“最终一致的”。因此,如果您向主人写入用户,辅助副本将“最终”为您提供您所写的数据。

+0

我对MongoDB相当陌生,但我会猜测这是一个单一的...此外,我不认为它进入该声明,它更新的用户似乎都在数据库中,并有之前已经更新(如果他们是新的或者dataReturned是“err”的话,他们不能进入竞技场开始)。我会添加一个控制台日志到这个语句来确保 – MadMikeGamerXL1