Почему onmessage работника выполняется после макрозадачи?Javascript

Форум по Javascript
Ответить
Anonymous
 Почему onmessage работника выполняется после макрозадачи?

Сообщение Anonymous »

Порядок выполнения цикла событий
Я изучаю, как работает цикл событий Javascript для будущей презентации, но столкнулся с неожиданным поведением с имеющейся у меня информацией. Проще говоря, когда я отправляю сообщение работнику, выполнение postmessage всегда происходит после setTimeout.
script.js:
new Worker('worker.js').postMessage('');

setTimeout( () => {
const now = new Date().toISOString();
console.log(`setTimeout execution: ${now}`);
}, 0);

worker.js:
onmessage = function (event) {
const now = new Date().toISOString();
console.log(`Worker execution: ${now}`);
}


Если вы хотите попробовать это в консоли самостоятельно:
const workerCode = `
self.onmessage = function (event) {
const now = new Date().toISOString();
self.postMessage("worker executed: " + now);
}`;

const blob = new Blob([workerCode], { type: 'application/javascript' });
const workerURL = URL.createObjectURL(blob);

const worker = new Worker(workerURL);

worker.onmessage = function (event) {console.log(event.data)};
worker.postMessage('');

setTimeout( () => {
const now = new Date().toISOString();
console.log(`setTimeout executed: ${now}`);
}, 0);

Мой вопрос
Поправьте меня, если я ошибаюсь, но цикл событий работает в следующем порядке:
  • Выполнить все задачи в стеке вызовов
  • Выполнить все задачи в микрозадаче
  • Выполнить задачу в задача макроса
  • Отрисовка графики/UI
Если это правда, то, зная, что setTimeout помещен в очередь макрозадач, которая буквально является последней очередью для чтения, почему почтовое сообщение выполняется после setTimeout? Если при синхронном выполнении он помещается в очередь (какой бы эта очередь ни была) раньше setTimeout?
Что я уже пробовал?
Я пытался поставить задержку, но это продолжает происходить, даже если setTimeout задерживается, поэтому я считаю, что причина этого не в том, что рабочий поток работает в параллельном с основным потоке. Пример:
setTimeout( () => {
const start = performance.now();
while (performance.now() - start < 1000) { };
const now = new Date().toISOString();
console.log(`Execution setTimeout: ${now}`);
}, 0);


Подробнее здесь: https://stackoverflow.com/questions/793 ... macro-task
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»