2016-04-05 7 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ループコードと統計情報を更新する関数の1つを投稿します(私のコードは効率的ではなく、おそらく不必要に長いですが、今のところ機能していることを確認しています)。

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(); 
     } 
    }); 

}; 

(更新機能の全ては、単に異なるDBフィールドの微調整同様のコードを有します)

マイク

答えて

0

あなたのコードはこのブロックに入っていますか?エラーがある場合、コードは自動的に失敗します。

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

また、単一のMongoDBサーバーまたはクラスタがありますか?クラスタ化されている場合、読み取りは「最終的に一貫性があります」。したがって、ユーザーをマスターに書き込むと、セカンダリー・レプリカはユーザーが書き込んだデータを「結局」提供します。

+0

私はかなりMongoDBの新人ですが、私はそれが1つだと推測しています...また、私はそれがその声明を入力しているとは思わない、それを更新しているユーザーはすべてデータベースにいるようです以前に更新されています(彼らが新しいかdataReturnedが "err"である場合に開始するためにアリーナに入ることはできません)。このステートメントにコンソールログを追加して、 – MadMikeGamerXL1

関連する問題