简体   繁体   English

如果事件触发后注册了WebSocket事件侦听器,为什么会起作用?

[英]Why does WebSocket event listeners work if they are registered after events are fired?

According to MDN docs , the WebSocket event listeners are registered after the connection is created, and the process is sequential: 根据MDN docs ,在创建连接会注册WebSocket事件侦听器,并且该过程是顺序的:

// Create WebSocket connection.
const socket = new WebSocket('ws://localhost:8080');

// Connection opened
socket.addEventListener('open', function (event) {
    console.log('ws connected');
});

// Listen for messages
socket.addEventListener('message', function (event) {
    console.log('Message from server ', event.data);
});

How does this work if events start firing before the listeners were registered? 如果事件在注册侦听器之前开始触发,这如何工作? Say, the connection opened before the open listener is registered, or messaged came in before the message listener is registered. 说,在注册open侦听器之前open了连接,或者在注册message侦听器之前收到了message

I would expect the events to be lost since the event listeners are not registered yet, according to the MDN doc on Concurrency model and Event Loop : 根据并发模型和事件循环MDN文档 ,由于事件监听器尚未注册,我希望事件会丢失。

In web browsers, messages are added anytime an event occurs and there is an event listener attached to it. 在Web浏览器中,只要事件发生并且附加了事件侦听器,便会添加消息。 If there is no listener, the event is lost. 如果没有侦听器,则事件将丢失。 So a click on an element with a click event handler will add a message--likewise with any other event. 因此,单击带有click事件处理程序的元素会添加一条消息-与其他任何事件一样。

I tried to add some expensive ops in between, but it seems that the open and message event listeners only trigger after all the event listeners are properly registered. 我尝试在两者之间添加一些昂贵的操作,但似乎open事件message监听器和message事件监听器仅在正确注册所有事件监听器之后才触发。 Are the WebSocket features async in nature? WebSocket功能本质上是异步的吗?

// Create WebSocket connection.
const socket = new WebSocket('ws://localhost:8080');

// expensive ops
for (var i = 5000; i >= 0; i--) {
  console.log('1');
}

// Connection opened
socket.addEventListener('open', function (event) {
    console.log('ws connected');
});

// expensive ops
for (var i = 5000; i >= 0; i--) {
  console.log('2');
}

// Listen for messages
socket.addEventListener('message', function (event) {
    console.log('Message from server ', event.data);
});

// prints "1"s, then "2"s, then "ws connected", then "Message from server"

You can't add events before an object is created so they have to be afterwards. 您无法在创建对象之前添加事件,因此必须在事件之后添加。 This all works because JavaScript is single-threaded and events are handled in the same thread so nothing can happen while code is running. 所有这些都是有效的,因为JavaScript是单线程的,并且事件是在同一线程中处理的,因此在代码运行时什么也不会发生。 You can delay the execution for a year and only after your code finishes will the runtime start handling any events that have arrived while it was running. 您可以将执行延迟一年,并且只有在代码完成后,运行时才会开始处理运行时到达的所有事件。 The socket might not even start connecting before your code finishes. 在您的代码完成之前,套接字甚至可能没有开始连接。

Therefore it's guaranteed that no events will go amiss. 因此,可以确保不会发生任何事件。

Mozilla Developer Network has a good explanation of the event loop , the “Run to Completion” talks about the nature of JS runtime. Mozilla开发人员网络很好地解释了事件循环 ,“运行完成”讨论了JS运行时的性质。

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

相关问题 为什么这些侦听器之一对Media API事件起作用,而对其他侦听器却不起作用? - Why does one of these listeners work for a Media API event but not the other? 为什么在 Ajax 调用后不触发 jQuery 事件? - Why does not a jQuery event gets fired after an Ajax call? 与浏览器 Javascript 的事件侦听器相比,事件 package 在 node.js 中如何工作 - How does events package work in node.js in contrast of event listeners of browser Javascript 注册捕获阶段的事件监听器在冒泡之前未触发 - 为什么? - Event listeners registered for capturing phase not triggered before bubbling - why? Easeljs中的位图不适用于事件侦听器吗? - Bitmap in Easeljs does not work with event listeners? 为什么在父元素上的事件之后触发了按钮上的事件? - Why are my events on button fired after events on parent elements? 为什么在 DOM 更改后不触发 touchmove 事件? - Why touchmove event is not fired after DOM changes? 为什么在.html()之后没有触发click事件? (jQuery的) - Why is the click event is not fired after .html() ? (jQuery) 为什么这个事件会被解雇? - Why does this event keep getting fired? 为什么我的听众不能在extjs上运行? - why my listeners does not work on extjs?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM