Понимание области действия обработчиков событий у веб-работников - PullRequest
0 голосов
/ 28 мая 2019

Рассмотрим следующий код веб-работника из: 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, обработчик события «message», определенный в doWork2, сначала выбирает событие.Затем запускается еще одно событие «message», которое обрабатывается обработчиком, определенным на главной странице, которая печатает сообщение.

Последовательность шагов такова.

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

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

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

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

Ответы [ 2 ]

0 голосов
/ 29 мая 2019

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

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

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

... интерфейс Worker отправляет сообщение во внутреннюю область работника

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

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

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

отправляетвернуть информацию в поток, который ее породил, с помощью метода DedicatedWorkerGlobalScope.postMessage.

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

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

0 голосов
/ 28 мая 2019

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

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

...