即使在hasOwnProperty检查之后,“无法读取未定义的属性”

时间:2019-09-13 12:59:47

标签: javascript node.js socket.io undefined

我一直在测试一个使用node.js和socket.io的Web应用程序。一切运行正常,但是在一个孤立的时间内进行的许多测试中,出现以下错误:

"TypeError: Cannot read property 'socket' of undefined"

这是错误所指的行:

for(var ID in playersPublic) {
        if(clients.hasOwnProperty(ID)) {
            clients[ID].socket.emit('players', playersPrivate[ID].playersToEmit);
            //The following line is where the error happened:
            clients[ID].socket.emit('food', playersPrivate[ID].foodToEmit);
        }
    }

绝对没有明显的原因会发生这种错误。我无法使它再次发生,我也不知道是什么具体情况造成的,但是我担心,因为使服务器崩溃(即使只有一次)也意味着代码逻辑中出现问题,一旦服务器崩溃,可能会导致更多错误或崩溃是公开的。此外,即使在使用hasOwnProperty明确检查是否定义了clients [ID]之后,也仍然不确定如何定义clients [ID],这使我感到困惑。更令人困惑的是,该错误涉及尝试访问clients [ID]的第二行。套接字,因此在前一个 行,访问它没有问题。在什么情况下会发生这种事情?

编辑:我添加了以下日志:

   if(clients.hasOwnProperty(ID)) {
        if(clients[ID] == null) {
            console.log('NULL BEFORE');
        }
        clients[ID].socket.emit('players', playersPrivate[ID].playersToEmit);
        if(clients[ID] == null) {
            console.log('NULL AFTER');
        }
        clients[ID].socket.emit('food', playersPrivate[ID].foodToEmit);
    }

哪个在控制台中产生以下输出:

NULL AFTER
G:\ioserver.js:262
                        clients[ID].socket.emit('food', playersPrivate[ID].foodToEmit);
                                    ^

TypeError: Cannot read property 'socket' of undefined

那么套接字发射到底会如何导致对象变为null / undefined?

1 个答案:

答案 0 :(得分:0)

显然,该错误是由以下一系列事件引起的。请注意,当套接字断开连接时,其在clients对象中的相应实例将被删除。因此,这种情况很少发生:

  1. 用户进行连接,并在客户端对象中创建一个具有其ID的实例
  2. 发射功能触发器。服务器检查客户端是否具有带有用户ID的密钥。是的服务器开始第一个发射(错误之前的行)
  3. 用户断开连接,并删除客户端对象中具有其ID的实例。
  4. 第一次发射完成。服务器尝试开始第二次发射,但是client [ID]不再存在。

通过添加三个日志来证明-一个在用户断开连接时记录,一个在第一次发射之前记录,一个在第二次发射之前记录(所有记录都带有用户的ID)。这是控制台中的结果:

emitting players...3pn9-inWwAn_cQaiAAAB
disconnecting user...3pn9-inWwAn_cQaiAAAB
emitting food...3pn9-inWwAn_cQaiAAAB
G:\ioserver.js:267
                        clients[ID].socket.emit('food', playersPrivate[ID].foodToEmit);
                                    ^

TypeError: Cannot read property 'socket' of undefined

因此,简单的解决方法是在第一次发射后再次检查client [ID]是否为空。