简单的 websocket 库(这在调用时丢失)[重复]

Simple websocket library (this lost on call) [duplicate]

提问人:javanoob 提问时间:2/14/2021 最后编辑:javanoob 更新时间:2/14/2021 访问量:61

问:

------注意:请参阅本文末尾的解决方案-------

我正在尝试制作一个简单的 websocket 库,它允许在连接时有一个回调,在收到消息时有一个回调,如果 5 秒后没有收到消息,则自动重新连接。

<html>

<script>
function ws(url, cb, concb){
    this.timeout = setTimeout(this.timeoutCB, 5000);
    this.url = url
    this.cb = cb;
    this.concb = concb;
    this.startConnection()
    }

ws.prototype.startConnection = () => {
    this.conn = new WebSocket(this.url);
    this.conn.onopen = () => {
        this.concb()
        console.log('Connected ');
        }

    this.conn.onclose = function() {
        console.log('Connection closed ');
        }

    this.conn.onmessage = (e) => {
        console.log('Received From Server: ' + e.data);
        clearTimeout(this.timeout);
        text = e.data;
        this.cb(text);
        this.timeout = setTimeout(this.timeoutCB, 5000);
        }
    }

ws.prototype.send = function(e) {
    this.conn.send(e);
    }

ws.prototype.timeoutCB = () => {
    alert("PRESS OK TO RECONNECT");
    this.timeout = setTimeout(this.timeoutCB, 5000);
    this.startConnection();
    }
    
w = new ws("127.0.0.1:9000", null, null);
</script>

</html>

我创建了一个方法,以便能够在构造函数和方法中调用它。问题是,当我从构造函数调用时,这不是 ws 对象,而是 .我不知道如何创建一个可以从构造函数和另一个方法(例如startConnectiontimeoutCBthis.startConnectionwindowstartConnectiontimeoutCB


-------------------溶液----------------------------------------------------

请查看 Nick Parsons 的评论。这是应用他的建议后对我有用的代码:

function ws(url, cb, concb){
    this.url = url
    this.cb = cb;
    this.concb = concb;
    this.startConnection()
    }

ws.prototype.startConnection = function() {
    this.timeout = setTimeout(() => this.timeoutCB(), 5000);
    console.log(this)
    this.conn = new WebSocket(this.url);
    this.conn.onopen = () => {
        this.concb()
        console.log('Connected ');
        }

    this.conn.onclose = () => {
        console.log('Connection closed ');
        }

    this.conn.onmessage = (e) => {
        console.log('Received From Server: ' + e.data);
        clearTimeout(this.timeout);
        text = e.data;
        this.cb(text);
        this.timeout = setTimeout(() => this.timeoutCB(), 5000);
        }
    }

ws.prototype.send = function(e) {
    this.conn.send(e);
    }

ws.prototype.timeoutCB = function() {
    alert("PRESS OK TO RECONNECT");
    this.startConnection();
    }

JavaScript websocket 这个 原型

评论

1赞 Nick Parsons 2/14/2021
调用 with 将使它在被调用时绑定到全局对象(即:)。您可以使用 绑定 ,也可以自己调用函数来保留上下文:timeoutCBsetTimeout(this.timeoutCB, 5000);timeoutCBthiswindowthissetTimeout(this.timeoutCB.bind(this), 5000);setTimeout(() => this.timeoutCB(), 5000);
0赞 javanoob 2/14/2021
我在setTimeout中理解了这个问题,但是我发现的第一个问题是在startConnection中,我认为这与我没有将对函数的引用传递给任何人,而是直接调用该函数不同。
1赞 Nick Parsons 2/14/2021
哦,是的,您还需要将箭头函数更改为常规函数,以便它可以绑定一个值(箭头函数使用周围范围)。所以() => {}function() {}thisthisws.prototype.timeoutCB = function() {...}
1赞 Nick Parsons 2/14/2021
周围作用域是定义函数的位置之外的范围,而不是调用函数的位置。定义函数的位置之外的作用域是全局作用域,因此 是默认的全局对象 - 。如果你在上面,你将能够看到周围范围内的内容thiswindowconsole.log(this)ws.prototype.timeoutCBthis
1赞 Nick Parsons 2/14/2021
如果您需要引用对象实例,则可以。否则,如果您没有在原型方法中使用,或者需要它引用周围的范围,那么使用箭头函数可能是首选。thisthisthis

答: 暂无答案