Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Пример макротаски и детальное объяснение
Макротаски (macrotasks) — это задачи в Event Loop JavaScript, которые выполняются после завершения выполнения текущего стека вызовов и после всех микрозадач (microtasks). К ним относятся, например, setTimeout, setInterval, setImmediate (Node.js), I/O операции и UI рендеринг. Приведу наглядный пример с объяснением работы:
Пример кода с макротаской
console.log('Начало скрипта');
// Макротаска: setTimeout
setTimeout(() => {
console.log('Макротаска setTimeout выполнена');
}, 0);
// Микротаска: Promise
Promise.resolve()
.then(() => {
console.log('Микротаска Promise выполнена');
});
console.log('Конец скрипта');
Результат выполнения
Начало скрипта
Конец скрипта
Микротаска Promise выполнена
Макротаска setTimeout выполнена
Пошаговое объяснение работы Event Loop
-
Синхронный код выполняется сразу:
- Сначала выводятся "Начало скрипта" и "Конец скрипта", так как это синхронные операции.
-
Микротаски имеют приоритет:
- Колбэк Promise.then() помещается в очередь микротаск и выполняется сразу после текущего стека, но перед любой макротаской.
-
Макротаска выполняется после микротаск:
- Колбэк
setTimeoutпомещается в очередь макротаск и ждёт, пока все микротаски (включая вложенные) завершатся.
- Колбэк
Детальный пример с вложенными задачами
setTimeout(() => {
console.log('Макротаска 1');
// Внутри макротаски создаётся микротаска
Promise.resolve()
.then(() => console.log('Микротаска внутри макротаски 1'));
}, 0);
setTimeout(() => {
console.log('Макротаска 2');
}, 0);
Promise.resolve()
.then(() => console.log('Микротаска 1'))
.then(() => console.log('Микротаска 2'));
console.log('Синхронный вывод');
Результат:
Синхронный вывод
Микротаска 1
Микротаска 2
Макротаска 1
Микротаска внутри макротаски 1
Макротаска 2
Ключевые особенности макротаск
- Механизм планирования:
setTimeout(callback, 0)не гарантирует мгновенное выполнение — минимальная задержка составляет 4 мс в браузерах (согласно спецификации HTML5). - Очередь макротаск: Каждая макротаска обрабатывается по одной за цикл Event Loop, между рендерингом.
- Примеры макротаск в реальных сценариях:
* **Обработка событий UI** (клики, скролл)
* **Сетевые запросы** (`fetch`, `XMLHttpRequest`)
* **Файловые операции** в Node.js
Сравнение с другими API
// setImmediate — макротаска в Node.js
setImmediate(() => {
console.log('Макротаска setImmediate');
});
// requestAnimationFrame — тоже макротаска, связанная с рендерингом
requestAnimationFrame(() => {
console.log('Макротаска requestAnimationFrame');
});
Практическое применение
Макротаски полезны для:
- Разделения тяжёлых вычислений на части, чтобы не блокировать UI.
- Отложенного выполнения кода после завершения всех срочных операций.
- Работы с асинхронными API, где порядок выполнения не критичен.
Важное правило
Event Loop всегда очищает всю очередь микротаск перед переходом к следующей макротаске. Это объясняет, почему Promise.then() выполняется раньше setTimeout, даже если последний имеет задержку 0 мс.
Понимание разницы между макротасками и микротасками критически важно для оптимизации производительности и предсказуемости асинхронного кода в JavaScript.