← Назад к вопросам
Приоритет выше у micro или у macro task
2.3 Middle🔥 101 комментариев
#Браузер и сетевые технологии
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Приоритет microtask vs macrotask
Microtask имеют БОЛЕЕ ВЫСОКИЙ приоритет чем macrotask. Это критически важно для понимания асинхронного выполнения кода в JavaScript.
Что такое Event Loop
Event Loop — это механизм, который определяет порядок выполнения кода в JavaScript. Он состоит из несколько этапов:
- Выполнение синхронного кода (call stack)
- Выполнение всех microtask (microtask queue)
- Выполнение одной macrotask (macrotask queue)
- Повтор с шага 2
Порядок выполнения
Call Stack (синхронный код)
|
v
Microtask Queue (ВЫСОКИЙ ПРИОРИТЕТ)
- Promises (.then, .catch, .finally)
- async/await
- MutationObserver
- queueMicrotask()
|
v (только после очистки всех microtask)
Macrotask Queue (НИЗКИЙ ПРИОРИТЕТ)
- setTimeout
- setInterval
- setImmediate
- requestAnimationFrame
- I/O операции
Практический пример
console.log("1. Синхронный код");
setTimeout(() => {
console.log("2. setTimeout (macrotask)");
}, 0);
Promise.resolve()
.then(() => {
console.log("3. Promise (microtask)");
});
console.log("4. Синхронный код");
// Результат:
// 1. Синхронный код
// 4. Синхронный код
// 3. Promise (microtask) — выполнится ПЕРЕД setTimeout!
// 2. setTimeout (macrotask)
Синхронный код выполняется первым (console.log 1 и 4). Затем выполняются все microtask (Promise), и только потом macrotask (setTimeout).
Более сложный пример
console.log("Начало");
// Macrotask
setTimeout(() => {
console.log("setTimeout 1");
Promise.resolve().then(() => {
console.log("Promise внутри setTimeout");
});
}, 0);
// Microtask
Promise.resolve()
.then(() => {
console.log("Promise 1");
setTimeout(() => {
console.log("setTimeout внутри Promise");
}, 0);
});
// Еще одна microtask
queueMicrotask(() => {
console.log("queueMicrotask");
});
console.log("Конец");
// Результат:
// Начало
// Конец
// Promise 1
// queueMicrotask
// setTimeout 1
// Promise внутри setTimeout
// setTimeout внутри Promise
Объяснение:
- Выполняются все console.log (синхронный код): "Начало", "Конец"
- Затем выполняются все microtask: "Promise 1", "queueMicrotask"
- Затем выполняется первая macrotask (первый setTimeout): "setTimeout 1"
- После каждой macrotask опять проверяются microtask: "Promise внутри setTimeout"
- Затем выполняется вторая macrotask: "setTimeout внутри Promise"
Примеры microtask
// 1. Promise callbacks
Promise.resolve().then(() => console.log("microtask"));
// 2. async/await
async function test() {
await Promise.resolve();
console.log("microtask"); // await это просто синтаксический сахар над .then
}
// 3. MutationObserver
const observer = new MutationObserver(() => {
console.log("microtask");
});
observer.observe(document.body, { childList: true });
// 4. queueMicrotask
queueMicrotask(() => {
console.log("microtask");
});
Примеры macrotask
// 1. setTimeout / setInterval
setTimeout(() => console.log("macrotask"), 0);
// 2. setImmediate (Node.js только)
setImmediate(() => console.log("macrotask"));
// 3. requestAnimationFrame
requestAnimationFrame(() => console.log("macrotask"));
// 4. I/O операции
fs.readFile("file.txt", () => console.log("macrotask"));
Почему это важно
Случай 1: Race condition с setTimeout
let data = null;
fetch("/api/data")
.then(response => response.json())
.then(json => {
data = json; // Это microtask
});
setTimeout(() => {
console.log(data); // Это выполнится ПОСЛЕ того как данные загружены!
}, 0);
Случай 2: Оптимизация перерисовок DOM
// Плохо: requestAnimationFrame нужно для правильной синхронизации с браузером
setTimeout(() => {
element.style.color = "red";
}, 0);
// Хорошо: используем requestAnimationFrame
requestAnimationFrame(() => {
element.style.color = "red";
});
Заключение
Приоритет ясен: microtask > macrotask. Все microtask выполняются перед тем, как браузер перейдет к следующей macrotask. Это важно помнить при отладке асинхронного кода и для понимания timing-зависимых проблем.