Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Какие знаешь очереди в Event Loop
Event Loop - это механизм, который управляет выполнением кода в JavaScript. В нём используется несколько типов очередей для разных операций.
Основная структура Event Loop
Event Loop имеет три основные очереди:
// 1. Call Stack (стек вызовов) - синхронный код
// 2. Microtask Queue (очередь микротасок)
// 3. Macrotask Queue (очередь макротасок)
// Порядок выполнения:
// 1. Выполняются синхронный код (Call Stack)
// 2. Все микротаски (Microtask Queue)
// 3. Одна макротаска (Macrotask Queue)
// 4. Повторяется
Microtask Queue (Очередь микротасок)
Микротаски имеют БОЛЕЕ ВЫСОКИЙ приоритет и выполняются ЕЩЁ ДО перейти к макротаскам:
console.log('1. Синхронный код'); // Выведет 1
Promise.resolve().then(() => {
console.log('3. Микротаска (Promise)'); // Выведет 3
});
setTimeout(() => {
console.log('5. Макротаска (setTimeout)'); // Выведет 5
}, 0);
console.log('2. Ещё синхронный код'); // Выведет 2
// Порядок вывода: 1, 2, 3, 5
Что входит в Microtask Queue:
- Promises (
.then(),.catch(),.finally()) queueMicrotask()- прямой доступ к очередиMutationObserverprocess.nextTick()в Node.js (имеет ещё более высокий приоритет)
// Примеры микротасок
Promise.resolve().then(() => console.log('Promise'));
queueMicrotask(() => console.log('queueMicrotask'));
const observer = new MutationObserver(() => {
console.log('MutationObserver');
});
observer.observe(document.body, { childList: true });
document.body.innerHTML = '<div></div>'; // Триггер
Macrotask Queue (Очередь макротасок)
Макротаски имеют БОЛЕЕ НИЗКИЙ приоритет. После каждой макротаски выполняются ВСЕ микротаски:
console.log('Start'); // 1
setTimeout(() => {
console.log('Макротаска 1'); // 3
Promise.resolve().then(() => {
console.log('Микротаска после макро 1'); // 4
});
}, 0);
setTimeout(() => {
console.log('Макротаска 2'); // 6
}, 0);
Promise.resolve().then(() => {
console.log('Микротаска'); // 2
});
console.log('End'); // 1
// Порядок: Start, End, Микротаска, Макротаска 1, Микротаска после макро 1, Макротаска 2
Что входит в Macrotask Queue:
setTimeout()setInterval()setImmediate()(Node.js)requestAnimationFrame()- немного особенный (выполняется перед render)- I/O операции
- UI события (click, scroll и т.д.)
Полный цикл Event Loop
console.log('Синхронный 1'); // 1
setTimeout(() => {
console.log('Макротаска');
Promise.resolve().then(() => console.log('Микротаска в макротаске'));
}, 0);
Promise.resolve()
.then(() => {
console.log('Микротаска 1');
queueMicrotask(() => console.log('Вложенная микротаска'));
})
.then(() => console.log('Микротаска 2'));
console.log('Синхронный 2'); // 2
// Вывод:
// 1. Синхронный 1
// 2. Синхронный 2
// 3. Микротаска 1
// 4. Вложенная микротаска
// 5. Микротаска 2
// 6. Макротаска
// 7. Микротаска в макротаске
requestAnimationFrame() - особый случай
rAF выполняется в особой позиции - между макротаской и рендерингом:
console.log('Start');
requestAnimationFrame(() => {
console.log('rAF'); // Выполнится перед render
});
setTimeout(() => {
console.log('setTimeout');
}, 0);
Promise.resolve().then(() => {
console.log('Promise');
});
console.log('End');
// Порядок
// Start, End, Promise, setTimeout, rAF (перед render)
Практический пример: оптимизация
// BAD - синхронное обновление DOM в цикле (blocking)
for (let i = 0; i < 1000; i++) {
document.body.innerHTML += `<div>${i}</div>`;
}
// GOOD - используем microtasks
const fragments = [];
for (let i = 0; i < 1000; i++) {
fragments.push(`<div>${i}</div>`);
}
Promise.resolve().then(() => {
document.body.innerHTML = fragments.join('');
});
// BETTER - используем requestAnimationFrame для синхронизации с refresh rate браузера
requestAnimationFrame(() => {
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const div = document.createElement('div');
div.textContent = i;
fragment.appendChild(div);
}
document.body.appendChild(fragment);
});
Визуальная схема приоритетов
Высокий приоритет:
1. Call Stack (синхронный код)
2. process.nextTick() (только Node.js)
3. Microtask Queue (Promise, queueMicrotask, MutationObserver)
4. requestAnimationFrame()
5. Render (перерисовка страницы)
6. Macrotask Queue (setTimeout, setInterval, I/O)
Низкий приоритет
Практический совет
// Если нужна низкая задержка - используй Microtask
Promise.resolve().then(() => {
updateUI();
});
// Если нужна синхронизация с render - используй rAF
requestAnimationFrame(() => {
animateElement();
});
// Если задача не срочная - используй Macrotask
setTimeout(() => {
trackAnalytics();
}, 0);
Понимание Event Loop критично для написания высокопроизводительного кода и избежания блокировок UI.