Node.js崩溃 - 异步问题或其他什么?

时间:2013-12-03 18:17:40

标签: arrays node.js asynchronous logic

我的节点服务器上发生了崩溃,我无法弄清楚它是如何在逻辑上发生的。我没有亲自责备,但根据bugsnag,它在上周发生了几次。我们非常感谢您对可能发生的原因以及有关其他日志记录以帮助调试的建议。

我有一个2人游戏,每个人都是一手牌,然后需要从他们手中选择两张牌来弃牌。丢弃是同时进行的,因此玩家可以在不同时刻或同一时刻丢弃。这是我的丢弃功能:

Game.prototype.discard = function(socket, msg) {
  var self = this;
  socket.get('playerNum', function (err, playerNum) {
    self.crib.push(self.cards[playerNum].splice(msg.cards[0],1)[0]);
    self.crib.push(self.cards[playerNum].splice(msg.cards[1]-1,1)[0]);
    for (var i = 0; i < self.cards[playerNum].length; i++) //add cards kept as unpegged
      self.currentUnPeggedCards.push(self.cards[playerNum][i]);
    socket.broadcast.in('gamea' + self.tableNumber).emit('other player discarded');
    if (self.crib.length == CARDS_PER_CRIB) { //both players discarded
      var jsonGame = self.buildJSON('starter');
      self.dbConnection.query("UPDATE savedgames SET game = '"+jsonGame+"' WHERE room = 'a' and player1_id = "+self.seatedPlayers[0][2]+" and player2_id = "+self.seatedPlayers[1][2]+";");
      if (playerNum == self.dealer)
        socket.broadcast.in('gamea' + self.tableNumber).emit('cut starter card');
      else
        socket.emit('cut starter card');
    }
    else {
      var jsonGame = self.buildJSON('discard');
      self.dbConnection.query("UPDATE savedgames SET game = '"+jsonGame+"' WHERE room = 'a' and player1_id = "+self.seatedPlayers[0][2]+" and player2_id = "+self.seatedPlayers[1][2]+";");
   }
  });
}

msg参数从客户端传入,并且是由用户切换两张卡然后选择丢弃而构建的。以下是生成msg的客户端代码:

function clickedDiscard() {
  if (myTurnButton) {
    var discards = [];
    var keepCards = [];
    for (var i=0; i<6; i++) {
      if (cardsClicked[i])
        discards.push(i);
      cardsClicked[i] = false;
    }
    numCardsClicked = 0;
    socket.emit('discard',{cards:discards});       
  }
}

所以它将两张牌推送到self.crib(其中包含两个玩家的丢弃牌),然后它检查两个玩家是否已经丢弃(通过查看self.crib的长度,然后我正在建立一个存储json对象代表游戏的当前状态,因此如果人们断开连接,他们可以恢复,等等。

崩溃发生在我的buildJSON函数中。这是该函数的完整代码(根据要求):

Game.prototype.buildJSON = function(state) {
  console.log('starting build json');
  var self = this;
  var stateStr = '"state":"'+state+'",';
  var scoreStr = '"score":['+self.score+'],';
  var winsStr = '"wins":['+self.wins+'],';
  var mostRecentPtsStr = '"mostRecentPts":['+self.mostRecentPts+'],';
  var mostRecentCardPtsStr = '"mostRecentCardPts":['+self.mostRecentCardPts+'],';
  var mostRecentCountStr = '"mostRecentCount":['+self.mostRecentCount+'],';
  var dealerStr = '"dealer":'+self.dealer+',';
  var dealsFirstStr = '"dealsFirst":'+self.dealsFirst+',';
  var peggerStr = '"pegger":'+self.currentPegger+',';
  var cardNamesStr = '"hands":[';
  for (var i=0; i<self.cards.length;i++) {
    cardNamesStr += '[';
    for (var j=0; j<self.cards[i].length;j++) {
      cardNamesStr += '"'+self.cards[i][j].getName()+'"';
      if (j==self.cards[i].length-1)
        cardNamesStr += ']';
      else
        cardNamesStr += ',';
    }
    if (i!=self.cards.length-1)
      cardNamesStr += ',';
  }
  cardNamesStr += '],';
  var cribStr = '"crib":[';
  for (var i=0;i<self.crib.length;i++) {
    cribStr += '"'+self.crib[i].getName()+'"';
    if (i!=self.crib.length-1)
       cribStr += ',';
  }
  cribStr += '],';
  var starterStr = '';
  if (self.starterCard != null)
    starterStr = '"starter":"'+self.starterCard.getName()+'",';
  var deckStr = '"deck":[';
  var deckCards = self.deck.getCards();
  for (var i=0;i< deckCards.length;i++) {
    deckStr += '"'+deckCards[i].getName()+'"';
    if (i!= deckCards.length-1)
        deckStr += ',';
  }
  deckStr += '],';
  var pegCountStr = '"count":'+self.currentPeggingCount+',';
  var peggedStr = '"pegged":[';
  for (var i=0; i<self.peggedCards.length;i++) {
    peggedStr += '[';
    for (var j=0; j<self.peggedCards[i].length;j++) {
      peggedStr += '"'+self.peggedCards[i][j].getName()+'"';
      if (j!=self.peggedCards[i].length-1)
        peggedStr += ',';
    }
    peggedStr += ']';
    if (i!=self.peggedCards.length-1)
      peggedStr += ',';
  }
  peggedStr += '],';
  var currentPeggedStr = '"currentPegged":[';
  for (var i=0;i<self.currentPeggedCards.length;i++) {
    currentPeggedStr += '"'+self.currentPeggedCards[i].getName()+'"';
    if (i!=self.currentPeggedCards.length-1)
        currentPeggedStr += ',';
  }
  currentPeggedStr += '],';
  var currentUnPeggedStr = '"currentUnPegged":[';
  for (var i=0;i<self.currentUnPeggedCards.length;i++) {
    currentUnPeggedStr += '"'+self.currentUnPeggedCards[i].getName()+'"';
    if (i!=self.currentUnPeggedCards.length-1)
        currentUnPeggedStr += ',';
  }
  currentUnPeggedStr += ']';
  var gameJSON = '{' + stateStr + scoreStr + winsStr + mostRecentPtsStr + mostRecentCardPtsStr +     mostRecentCountStr + dealerStr + dealsFirstStr + peggerStr + cardNamesStr + cribStr + starterStr + deckStr + pegCountStr + peggedStr + currentPeggedStr + currentUnPeggedStr + '}';
  console.log('json built');
  return gameJSON;
} 

在调用getName()时发生崩溃,错误是:无法调用未定义的方法'getName'

此时,我不确定这是怎么发生的。根据定义,for循环在对象的长度上,因此循环中的每个索引处必须有一个元素。然而,显然没有,因为对象是未定义的。这是因为异步问题而发生的吗?当推送到数组时,在将对象实际添加到数组本身之前,它是否以某种方式增加了数组的长度?我想有可能我从原始数组中拼接出来的是未定义的?很难过。

0 个答案:

没有答案