Почему прослушиватели событий WebSocket работают, если они зарегистрированы после запуска событий? - PullRequest
0 голосов
/ 13 февраля 2019

В соответствии с MDN документами , прослушиватели событий 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);
});

Как этоработать, если события начинают срабатывать до того, как слушатели будут зарегистрированы?Скажем, соединение открылось до того, как прослушиватель open зарегистрирован, или сообщение пришло до того, как зарегистрировано прослушиватель message.

Я ожидаю, что события будут потеряны, так как прослушиватели событий еще не зарегистрированы,в соответствии с документом MDN о модели параллелизма и циклом событий :

В веб-браузерах сообщения добавляются каждый раз, когда происходит событие, и к нему подключен прослушиватель событий.Если слушателя нет, событие теряется.Таким образом, щелчок по элементу с обработчиком события click добавит сообщение - аналогично любому другому событию.

Я попытался добавить несколько дорогих операций между ними, но кажется, что openи message прослушиватели событий срабатывают только после того, как все прослушиватели событий правильно зарегистрированы.Являются ли функции 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"

1 Ответ

0 голосов
/ 13 февраля 2019

Вы не можете добавлять события до создания объекта, поэтому они должны быть после.Все это работает, потому что JavaScript является однопоточным, а события обрабатываются в одном потоке, поэтому ничего не может произойти во время выполнения кода.Вы можете отложить выполнение на год, и только после завершения кода среда выполнения начнет обрабатывать любые события, поступившие во время его выполнения.Сокет может даже не начать соединяться до того, как ваш код завершит работу.

Поэтому гарантируется, что ни одно событие не пройдет.

В Mozilla Developer Network есть хорошее объяснение цикла событий , в «Run to Completion» рассказывается о природе времени выполнения JS.

...