Рассмотрим следующий код для веб-работников: https://www.html5rocks.com/en/ учебные пособия / рабочие / основы /

Веб-страница:

<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 рекурсивный?

0
k29 28 Май 2019 в 11:09

2 ответа

Лучший ответ

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

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

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

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

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

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

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

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

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

Источник: https://developer.mozilla.org/en- США / документы / Web / API / рабочий / PostMessage

0
k29 29 Май 2019 в 07:13

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

Подробнее: https://developer.mozilla.org/en-US / документы / Web / JavaScript / EventLoop

0
Nasaralla 28 Май 2019 в 08:30