繁体   English   中英

我如何保证websocket onopen被调用

[英]How can I guarantee that websocket onopen to be called

我在javascript使用WebSocket WebSocket需要将该url作为构造函数参数,并立即尝试连接。 我只能在构造它之后设置onopen方法。

因此,如果WebSocket在设置onopen之前已经建立了连接,那么我会错过onopen事件!

如何避免这种情况?

要模拟它:

一种)

1)在Chrome中,打开websocket 2)按F12打开开发人员工具。 3)打开控制台4)一次复制并粘贴所有这些代码! 输入!

uri = "ws://echo.websocket.org?encoding=text";
websocket = new WebSocket(uri);
websocket.onopen = function(evt) { console.log('EHE')};

B)

重复1-2-3

4)复制并粘贴这些代码并运行

uri = "ws://echo.websocket.org?encoding=text";
websocket = new WebSocket(uri);

5)等一下

6)运行这段代码:

websocket.onopen = function(evt) { console.log('EHE')};

结果:

在A)中,调用onopen。 在B)中我们错过了!

由于Java脚本具有单线程事件驱动的特性,因此您描述的内容不会在实际代码中发生。 只有在您当前的Java语言部分完成后,才能触发“打开”事件。 因此,您将始终能够在事件发生之前设置onopen事件处理程序。

在调试器或控制台中插入人为的暂停是在实际代码中不会发生的人为情况。

实际代码中发生的事情是这样的:

  1. 您调用new WebSocket(uri)
  2. webSocket内部结构启动webSocket连接(异步操作)
  3. 该连接完成之前,webSocket构造函数立即返回。
  4. 其余代码将运行(包括分配.onopen属性和设置事件处理程序。
  5. Java解释器完成了您的代码的运行,并返回到事件循环。
  6. 如果到目前为止,如果webSocket已连接,则事件队列中将存在一个open事件,而Javascript将触发该事件,从而导致您的.onopen处理程序被调用。
  7. 如果open事件尚未完成,则Javascript将等待下一个事件插入事件队列并运行它,一遍又一遍地重复该过程。 最终,这些事件之一将是您的open事件。

关键在于通过异步事件调用.onopen 因此,它必须经过Javascript事件队列。 而且,直到您当前的Javascript部分完成并返回到解释器之前,事件队列中的任何事件都无法运行。 这就是JavaScript的“事件驱动”本质的工作方式。 所以,因为这个架构的,你不能错过onopen只要您安装事件.onopen处理在Javascript中的相同部分调用构造函数。


如果给您带来任何舒适,node.js中有数十个API都依赖于同一概念。 例如,当您使用fs.createReadStream(filename)创建文件流时,必须创建该流,然后添加事件处理程序(这些事件处理程序之一用于open事件)。 相同的逻辑在那里适用。 由于Javascript具有事件驱动的特性,因此没有竞争条件。 在其他Javascript运行之前,无法触发open事件或error事件,因此,您始终有机会在调用事件处理程序之前先安装它们。

如果可以同步检测到错误(例如文件名错误或uri error )并可能立即触发error事件,请使用类似setImmediate(function() { /* send error event here*/ })来确保只有在您的代码有机会安装事件处理程序之后,才会触发error事件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM