Приведи пример macro-task
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Пример Macro-Task в JavaScript: setTimeout
Что такое Macro-Task?
Macro-task (макрозадача) – это задача, которая выполняется в рамках Event Loop после очистки стека вызовов и Micro-task очереди. К макрозадачам относятся операции, связанные с вводом-выводом, таймерами, рендерингом и событиями пользовательского интерфейса.
Пример с setTimeout
Классический пример макрозадачи – setTimeout, который позволяет отложить выполнение функции на указанное время. Рассмотрим подробный пример с пояснениями работы Event Loop.
console.log('Начало скрипта'); // 1. Синхронный код
setTimeout(() => {
console.log('Макрозадача: таймер 0 мс'); // 4. Макрозадача
}, 0);
Promise.resolve().then(() => {
console.log('Микрозадача: промис'); // 3. Микрозадача
});
console.log('Конец синхронного кода'); // 2. Синхронный код
Результат выполнения:
Начало скрипта
Конец синхронного кода
Микрозадача: промис
Макрозадача: таймер 0 мс
Детальное объяснение процесса
Последовательность выполнения:
-
Синхронная фаза:
- Выполняются все синхронные операции, включая
console.log(). setTimeoutрегистрирует колбэк в Web API браузера.Promise.resolve().then()добавляет колбэк в очередь микрозадач.
- Выполняются все синхронные операции, включая
-
Фаза микрозадач:
- После завершения синхронного кода Event Loop проверяет очередь micro-task queue.
- Выполняется колбэк промиса:
console.log('Микрозадача: промис').
-
Фаза макрозадач:
- После полной очистки очереди микрозадач Event Loop переходит к macro-task queue.
- Выполняется колбэк таймера:
console.log('Макрозадача: таймер 0 мс').
Практический пример с вложенными задачами
Рассмотрим более сложный сценарий с несколькими типами задач:
console.log('=== Старт ===');
setTimeout(() => {
console.log('Макрозадача 1: таймер 100 мс');
}, 100);
setTimeout(() => {
console.log('Макрозадача 2: таймер 0 мс');
Promise.resolve().then(() => {
console.log('Микрозадача внутри макрозадачи');
});
}, 0);
Promise.resolve().then(() => {
console.log('Микрозадача 1');
setTimeout(() => {
console.log('Таймер из микрозадачи');
}, 0);
});
Promise.resolve().then(() => {
console.log('Микрозадача 2');
});
console.log('=== Финиш синхронного кода ===');
Ожидаемый вывод:
=== Старт ===
=== Финиш синхронного кода ===
Микрозадача 1
Микрозадача 2
Макрозадача 2: таймер 0 мс
Микрозадача внутри макрозадачи
Таймер из микрозадачи
Макрозадача 1: таймер 100 мс
Ключевые особенности макрозадач
Типичные источники макрозадач:
- Таймеры:
setTimeout,setInterval - События DOM:
click,load,keydown - Сетевые запросы:
fetch,XMLHttpRequest - Рендеринг: операции отрисовки страницы
- I/O операции: чтение файлов в Node.js
Важные нюансы:
- Приоритетность: Микрозадачи имеют более высокий приоритет и выполняются после каждой макрозадачи.
- Вложенность: Макрозадачи могут генерировать новые микрозадачи и наоборот.
- Тайминг: Аргумент
setTimeoutуказывает минимальную задержку, а не гарантированное время выполнения.
Практическое применение
Понимание разницы между макро- и микрозадачами помогает оптимизировать производительность веб-приложений. Например, при обработке больших объемов данных можно разбивать операции на части, используя setTimeout, чтобы не блокировать основной поток и дать браузеру возможность выполнить рендеринг.
function processChunk(data, index = 0) {
if (index >= data.length) return;
// Обработка части данных
console.log(`Обработан элемент ${index}: ${data[index]}`);
// Планируем следующую итерацию как макрозадачу
setTimeout(() => {
processChunk(data, index + 1);
}, 0);
}
const largeArray = new Array(1000).fill().map((_, i) => i);
processChunk(largeArray);
Этот подход позволяет избежать заморозки интерфейса при выполнении ресурсоемких операций, так как между итерациями браузер получает возможность обрабатывать другие задачи, включая пользовательский ввод и анимации.