[英]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
事件处理程序。
在调试器或控制台中插入人为的暂停是在实际代码中不会发生的人为情况。
实际代码中发生的事情是这样的:
new WebSocket(uri)
.onopen
属性和设置事件处理程序。 open
事件,而Javascript将触发该事件,从而导致您的.onopen
处理程序被调用。 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.