Я изучаю, как работает цикл событий 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( () => {
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
Мобильная версия