Firebase中的竞争条件-函数触发两次

时间:2019-02-06 18:22:24

标签: javascript firebase firebase-realtime-database race-condition

我正在开发一款多人剪刀石头布游戏,并且在更新Firebase中的数据时遇到一些问题。我认为比赛条件正在发生。在给定比赛的结果以及两个播放器之一(我在两个浏览器窗口中打开它进行测试)上,都有一次child_added侦听器,结果有时会翻倍。我将在屏幕上看到两次附加的游戏结果,并且得分将增加两倍。同样,这仅适用于两个玩家之一。我似乎无法弄清楚到底是什么导致结果使孩子添加了两次木柴射击并使一位玩家的得分翻倍。这是有问题的代码示例:

  //Function to increase move count
function progressMove(num) {
  database
    .ref("/moves")
    .child("/move")
    .set(num);
}

//Listener for when move variable changes
database.ref("/moves").on("value", function(snap) {
  console.log("Move just changed to " + snap.val().move);
  if (snap.val().move === 1) {
    $(".enter-name").slideUp("slow")
    playerOneThrow(snap.val().move);
  }
  if (snap.val().move === 2) {
    playerTwoThrow(snap.val().move);
  }
  if (snap.val().move === 3) {
      console.log("Move is 3, evaluating match")
    evaluateMatch();
    database.ref("/results/gameresult").remove()
    console.log("removed the results node")
  }
});

function playerOneThrow() {
  $(".details").text("Player 1, choose your throw");
  $(".p1-hands").on("click", playerOneChooseHand);
}

function playerOneChooseHand() {
  $(".p1-hands").off()
  let hand = $(this).attr("data-value");
  console.log("Player 1 chose" + hand);
  progressMove(2);
  database.ref("/throws/p1throw").child("/throwVal").set(hand);
}

function playerTwoThrow() {
  $(".details").text("Player 1 has thrown, player 2, choose your throw");
  $(".p2-hands").on("click", playerTwoChooseHand);
}

function playerTwoChooseHand() {
  $(".p2-hands").off()
  progressMove(3);
  console.log("Player 2 hand clicked");
  let hand = $(this).attr("data-value");
  console.log("Player 2 chose" + hand);
  database.ref("/throws/p2throw").child("/throwVal").set(hand);
}

function evaluateMatch() {
    database.ref("/throws/")
    .once("value")
    .then(function(throwsnap) {
        console.log("Displaying throws node once for match evaluation")
        console.log(throwsnap.val())
            let p1throw = throwsnap.val().p1throw.throwVal;
            let p2throw = throwsnap.val().p2throw.throwVal;
            if (p1throw === p2throw){
                database.ref('/results/gameresult').child("/outcome").set("tie")
            } else if(p1throw === "rock"){
                if(p2throw === "paper"){
                database.ref('/results/gameresult').child("/outcome").set("p2 wins")
                } else if(p2throw === "scissors")
                database.ref('/results/gameresult').child("/outcome").set("p1 wins")
            } else if (p1throw === "paper"){
                if(p2throw === "rock"){
                database.ref('/results/gameresult').child("/outcome").set("p1 wins")
                } else if (p2throw === "scissors"){
                database.ref('/results/gameresult').child("/outcome").set("p2 wins")
                }
            } else if(p1throw === "scissors"){
                if(p2throw === "paper"){
                database.ref('/results/gameresult').child("/outcome").set("p1 wins")
                } else if (p2throw === "rock"){
                 database.ref('/results/gameresult').child("/outcome").set("p2 wins")
                }
            }
        });
    }

//Listens for change in results, triggered by setting outcome and results above

database.ref('/results/gameresult').on("child_added",function(resultsnap){
    console.log("Displaying results node because a child was added", resultsnap.val())
    database.ref("/throws/").once("value").then(function(throwsnap) {
          console.log("Displaying the throws node just once since a child was added to the game results node")
        console.log(throwsnap.val()) 
          if(resultsnap.val() === "tie"){
              ties++
          } else if (resultsnap.val() === "p1 wins"){
              p1wins++
              p2losses++
          } else if(resultsnap.val() === "p2 wins"){
              p2wins++
              p1losses++
          }
          database.ref("/moves").child("/move").set(1); //Bring game back to p1throw point
          $(".details").prepend("The result was: " + resultsnap.val() + "<br><br>");

          $(".details").prepend(" Player 1 chose " + throwsnap.val().p1throw.throwVal + " and player 2 chose " + throwsnap.val().p2throw.throwVal + "<br><br>");
          console.log(ties + " ties")
          console.log(p1wins + " p1wins")
          console.log(p2wins + " p2wins") 
          //Update results on page 
          database.ref('/results/gameresult').on("value",function(snap){
            console.log("Updating screen for both because game result has changed")
            $("#p1-wins").text(p1wins + " ")
            $("#p2-wins").text(p2wins + " ")
            $("#p1-losses").text(p1losses + " ")
            $("#p2-losses").text(p2losses + " ")
            $(".ties").text(ties + " ")
        })
    });
})

0 个答案:

没有答案