Рассмотрим следующий код веб-воркера из: 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, первым получает событие. Затем он запускает другое событие «сообщение», которое подхватывается обработчиком, определенным на главной странице, который распечатывает сообщение.
Поток шагов такой.
Пожалуйста, ответьте на следующие 2 вопроса:
Вопрос 1: В шаге 2. выше, почему срабатывает обработчик в doWork2, но не обработчик на странице?
Вопрос 2: Почему на шаге 4 после запуска события из doWork2 обработчик на странице выполняется, а обработчик в doWork2 не выполняется рекурсивно?
причина, по которой прослушиватель событий doWorks2 срабатывает раньше, заключается в том, что javascript интерпретирует ваш код. Выполнение кода в Javascript происходит при асинхронных функциях в 2-х направлениях. Существует стек вызовов, в котором есть команды, которые выполняются в синхронном порядке или классической последовательности, а затем для асинхронных функций существует очередь сообщений, которая ставит события в очередь в том порядке, в котором они были добавлены.
Подробнее: https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
@Титус прав. Я отредактировал нижнюю часть вопроса, чтобы прояснить, что я не понимаю.
Получается, что есть две реализации 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
Я думаю, что ОП спрашивает, почему оба обработчика событий не запускаются при отправке сообщения.