Понимание области действия обработчиков событий в веб-воркерах

Рассмотрим следующий код веб-воркера из: https://www.html5rocks.com/en/tutorials/workers/basics/.

Страница в Интернете:

<button onclick = "sayHI()">Say HI</button>
<button onclick = "unknownCmd()">Send unknown command</button>
<button onclick = "stop()">Stop worker</button>
<output id = "result"></output>

<script>
  function sayHI() {
    worker.postMessage({'cmd': 'start', 'msg': 'Hi'});
  }

  function stop() {
    // worker.terminate() from this script would also stop the worker.
    worker.postMessage({'cmd': 'stop', 'msg': 'Bye'});
  }

  function unknownCmd() {
    worker.postMessage({'cmd': 'foobard', 'msg': '???'});
  }

  var worker = new Worker('doWork2.js');

  worker.addEventListener('message', function(e) {
    document.getElementById('result').textContent = e.data;
  }, false);
</script>

Затем в doWork2.js:

self.addEventListener('message', function(e) {
  var data = e.data;
  switch (data.cmd) {
    case 'start':
      self.postMessage('WORKER STARTED: ' + data.msg);
      break;
    case 'stop':
      self.postMessage('WORKER STOPPED: ' + data.msg +
                       '. (buttons will no longer work)');
      self.close(); // Terminates the worker.
      break;
    default:
      self.postMessage('Unknown command: ' + data.msg);
  };
}, false);

Таким образом, когда вы нажимаете SayHi, обработчик события «сообщение», определенный в doWork2, первым получает событие. Затем он запускает другое событие «сообщение», которое подхватывается обработчиком, определенным на главной странице, который распечатывает сообщение.

Поток шагов такой.

  1. Пользователь нажимает кнопку, вызывает событие сообщения.
  2. Обработчик в doWork2 выполняется.
  3. Обработчик в doWork2 вызывает событие сообщения
  4. Обработчик на веб-странице выполняется

Пожалуйста, ответьте на следующие 2 вопроса:

Вопрос 1: В шаге 2. выше, почему срабатывает обработчик в doWork2, но не обработчик на странице?

Вопрос 2: Почему на шаге 4 после запуска события из doWork2 обработчик на странице выполняется, а обработчик в doWork2 не выполняется рекурсивно?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
397
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

причина, по которой прослушиватель событий doWorks2 срабатывает раньше, заключается в том, что javascript интерпретирует ваш код. Выполнение кода в Javascript происходит при асинхронных функциях в 2-х направлениях. Существует стек вызовов, в котором есть команды, которые выполняются в синхронном порядке или классической последовательности, а затем для асинхронных функций существует очередь сообщений, которая ставит события в очередь в том порядке, в котором они были добавлены.

Подробнее: https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop

Я думаю, что ОП спрашивает, почему оба обработчика событий не запускаются при отправке сообщения.

Titus 28.05.2019 10:44

@Титус прав. Я отредактировал нижнюю часть вопроса, чтобы прояснить, что я не понимаю.

k29 28.05.2019 11:27
Ответ принят как подходящий

Получается, что есть две реализации postMessage на двух разных объектах.

Ответ на вопрос 1

При вызове worker.postMessage()

...the Worker interface sends a message to the worker's inner scope

И поэтому обработчик события сообщения на странице его не видит.

Ответ на вопрос 2

При вызове self.postMesssage self является глобальной областью действия рабочего процесса, реализация которой работает следующим образом:

sends back information to the thread that spawned it using the DedicatedWorkerGlobalScope.postMessage method.

Таким образом, он не вызывает себя рекурсивно, потому что событие сообщения видно только в потоке, который его породил.

Источник: https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage

Другие вопросы по теме