一般信息
我正在开发一个基于websocket的聊天系统。我试图通过使用OOP方法正确地做到这一点。这也是我决定选择es6的原因。
问题
在我的代码中,我在构造函数中初始化了几个变量。其中一个变量是一个布尔值,用于告诉我是否已经建立了与套接字的连接。它设置为false,应在Socket.onopen()
事件中更新为true。
我想在connect()
方法中使用此布尔值,以便如果用户在已连接时尝试再次连接,则会断开用户的连接。在建立连接后,有效地将连接按钮变为断开连接按钮。
问题在于它没有像我期望的那样更新布尔值。
代码(简化为相关代码)
class CB {
constructor(username) {
this.connected = false;
}
connect(){
// User already connected. Disconnect
if (this.connected) {
this.disconnect();
return;
}
const Socket = new WebSocket('ws://'+this.serverHost+':'+this.serverPort);
this.setSocketEvents(Socket);
this.socket = Socket;
}
setSocketEvents(Socket){
const obj = this;
Socket.onopen = function () {
// Update connected boolean
obj.connected = true;
};
}
}
如果在将其设置为true之前尝试console.log(obj.connected);
,则会按预期返回false。在它设定之后它也会回归真实。但是connect()
方法在this.connected
之后仍会返回false,如果之后调用的话。
我猜这是一个范围问题,或者我完全误解了这一切是如何运作的。所以我希望有人可以帮助我。
答案 0 :(得分:1)
这不是范围问题,它是计时问题:在一段时间内,您正在进行连接但尚未连接。你不允许这种可能性。
这样做的一个选择是拥有一个单独的connecting
标志。请参阅***
评论:
class CB {
constructor(username) {
this.connected = false;
this.connecting = false; // ***
}
connect(){
// *** If busy connecting, do nothing (or cancel the connection
// attempt or ...)
if (this.connecting) {
return;
}
// User already connected. Disconnect
if (this.connected) {
this.disconnect();
return;
}
const Socket = new WebSocket('ws://'+this.serverHost+':'+this.serverPort);
this.setSocketEvents(Socket);
this.socket = Socket;
}
setSocketEvents(Socket){
this.connecting = true;
Socket.onopen = () => { // *** No need for `const obj = this`, use an arrow function
// Update connected boolean
this.connected = true;
this.connecting = false; // ***
};
}
}
这个主题有很多变化。例如,您可以使用一个类似枚举的属性,而不是两个布尔值,其值为NOT_CONNECTED
,CONNECTING
和CONNECTED
。
附注:强烈建议不要使用名为connect
的方法根据状态断开连接。相反,有一个单独的disconnect
方法(显然你这样做,虽然没有显示)直接被调用。