[英]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.