es6 update constructor boolean not working

时间:2017-12-14 09:30:23

标签: javascript

一般信息
我正在开发一个基于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,如果之后调用的话。

我猜这是一个范围问题,或者我完全误解了这一切是如何运作的。所以我希望有人可以帮助我。

1 个答案:

答案 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_CONNECTEDCONNECTINGCONNECTED

附注:强烈建议不要使用名为connect的方法根据状态断开连接。相反,有一个单独的disconnect方法(显然你这样做,虽然没有显示)直接被调用。