MongoDB For Loop更新错误的用户



所以我一直在用Javascript编程Twitch聊天机器人,并使用MongoDB存储用户信息。有一个迷你游戏,在几次"攻击"后,怪物可以被击败,用户将获得战斗经验。有一系列在当前战斗中被奖励的用户,以及一份被击败的用户列表。他们仍然获得经验值,但他们的"胜利"没有更新。问题是,我使用for循环来执行此操作,直到它更新了数组中的每个用户。这是可行的,但非常有缺陷,我认为这是因为函数在数据库有机会赶上之前就已经循环了(不确定是否是这样,但这是我的假设)。基本上,当数据库试图更新用户时,它有时会多次更新同一个人,而不会更新其他人。

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

[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

您的代码是否进入过这个块?如果出现错误,代码将以静默方式失败。

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

另外,您有一个MongoDB服务器还是一个集群?如果它是集群的,则读取是"最终一致的"。因此,如果您将用户写入主副本,辅助副本将"最终"提供您写入的数据。

相关内容

最新更新