按下按钮

时间:2019-02-23 21:07:04

标签: javascript node.js socket.io

我正在尝试创建一个简单的NodeJS排行榜,并且正在使用socket.io进行客户端和服务器之间的实时连接。一切正常,但是按增加按钮后,页面崩溃了,我必须关闭它。在页面崩溃之前,我在浏览器控制台中看不到任何错误,并且在命令提示符中也没有错误,这是我从中运行应用程序的位置。

我想用socket.on('increase')实现的目的是弄清楚表中是否已经存在作为参数给出的名称。如果是,则替换表另一列中的得分值,如果不是,则在表中添加一个新行,并使用用户名和得分。

不过,我不知道为什么页面崩溃了。但是,我很确定这与usernameForm有关,因为当我删除它时,问题不再发生。

index.html

<!doctype html>
<html>
  <body>
    <form id="usernameForm">
      <input type="text" id="usernameFormInput" name="usernameFormInput">
      <input type="submit" value="Submit">
    </form>
    <div id="users"></div>
    <button id="increase">Increase</button><br>
    <span id="score">0</span><br>
    <table id="leaderboard">
      <tr>
        <th>Name</th>
        <th>Score</th>
      </tr>
    </table>

    <script src="/socket.io/socket.io.js"></script>
    <script>
      var socket = io();

      var playerName = "Jeff";
      var playerScore = 0;

      document.getElementById("increase").onclick = function() {
        playerScore += 1;
        document.getElementById("score").innerHTML = playerScore;
        socket.emit('increase', playerName, playerScore);
      };

      document.getElementById("usernameForm").onsubmit = function(e) {
        var newUsername = document.getElementById("usernameFormInput").value;
        socket.emit('newUser', newUsername);
        console.log("new user client");
        e.preventDefault();
      }

      socket.on('increase', function(user, score) {
        for (i = 0; i < document.getElementById("leaderboard").rows.length; i++) {
          if (document.getElementById("leaderboard").rows[i].cells[0].innerHTML == user) {
            document.getElementById("leaderboard").rows[i].cells[1].innerHTML = score;
          }
          else {
            var table = document.getElementById("leaderboard");
            var row = table.insertRow(0);
            var userCell = row.insertCell(0);
            var scoreCell = row.insertCell(0);
            userCell.innerHTML = user;
            scoreCell.innerHTML = score;
          }
        }
      });

      socket.on('newUser', function(name) {
        playerName = name;
        console.log("new user client cb");
      });

      socket.on('updateUsers', function(usernames) {
        document.getElementById('users').innerHTML = Object.values(usernames);
      });
    </script>
  </body>
</html>

app.js

var io = require('socket.io')(http);

var usernames = [];
var userScore = {};

var isUsernameTaken = function(data) {
    for (var i = 0; i <= Object.keys(usernames).length; i++) {
        console.log("loop entered");
        if(data == usernames[i]) {
          console.log("Username '" + data + "' is taken.")
          return true;
        } else {
          console.log("Username '" + data + "' is not taken.");
          usernames.push(data);
          updateUsers();
          return false;
        }
    }
}

var updateUsers = function() {
    io.emit('updateUsers', usernames);
    console.log(usernames);
};

io.on('connection', function(socket) {
  socket.on('increase', function(user, score) {
    userScore[user] = score;
    io.emit('increase', user, score);
  });

  socket.on('newUser', function(name) {
    console.log("new user server");
    if ( isUsernameTaken(name) ) {
      console.log("username taken");
    }
    else {
      console.log("new user server loop");
      usernames.push(name);
      io.emit('newUser', name);
    }
  });
});

http.listen(4000, function(){
  console.log('listening on *:4000');
});

我对长代码的代码表示歉意,但是当我尝试维护MCVE时,我还需要包括所有相关代码以找出问题的根源。

2 个答案:

答案 0 :(得分:1)

事件发射器是同步的。 .emit('increase'似乎正在同步触发socket.on('increase',因此创建了一个使网页崩溃的无限循环。如果支持socket.once,请尝试执行此操作;否则,在第一次触发socket.on('increase'事件侦听器后,将其删除,如果此操作可以修复页面,则您知道原因所在。

答案 1 :(得分:1)

您的问题出在.insertRow上,您必须使用表长度的大小。

这是一个可能的解决方案:

import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';

// Importing Components
import { AppComponent } from './app.component';
import { ModalsComponent } from '@advent/components';


@NgModule({
  declarations: [
    AppComponent,
    ModalsComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

由于它是复制行,所以我也对代码进行了一些更改