Чем отличаются микротаски и макротаски?nodejs-23
Основные понятия
Микротаски
- Выполняются сразу после текущей синхронной задачи
- Имеют высший приоритет в Event Loop
- Примеры:
- Promise callbacks (
then/catch/finally
)
queueMicrotask()
process.nextTick()
(Node.js specific, но похоже)
Макротаски
- Выполняются в следующих итерациях Event Loop
- Имеют более низкий приоритет
- Примеры:
setTimeout/setInterval
setImmediate
(Node.js)
- I/O операции
- UI rendering (в браузере)
Ключевые различия
Характеристика | Микротаски | Макротаски |
Приоритет | Высший | Низкий |
Очередь | Собственная очередь | Очередь Event Loop |
Когда выполняются | Между макротасками | В следующих тиках Event Loop |
Примеры | Promise, process.nextTick | setTimeout, setImmediate |
Пример выполнения
console.log('Синхронный код 1');
setTimeout(() => console.log('setTimeout'), 0);
Promise.resolve()
.then(() => console.log('Promise 1'))
.then(() => console.log('Promise 2'));
queueMicrotask(() => console.log('queueMicrotask'));
console.log('Синхронный код 2');
Вывод:
- Синхронный код 1
- Синхронный код 2
- Promise 1
- queueMicrotask
- Promise 2
- setTimeout
Глубокое объяснение
1. Механизм выполнения в Event Loop
Микротаски:
- Выполняются до перехода к следующей фазе Event Loop
- Обрабатываются до следующего макротаска
- Очередь должна быть полностью очищена перед продолжением
Макротаски:
- Выполняются в соответствующих фазах Event Loop
- Одна макротаска за одну итерацию цикла (в общем случае)
2. Особенности Node.js
process.nextTick
- особый случай:
- Технически не микротаска, но ведет себя похоже
- Имеет даже более высокий приоритет, чем Promise
Promise.resolve().then(() => console.log('Promise'));
process.nextTick(() => console.log('nextTick'));
// nextTick выполнится первым
3. Проблемы и подводные камни
Рекурсивные микротаски:
function recursiveMicrotask() {
Promise.resolve().then(recursiveMicrotask);
}
// Полностью заблокирует Event Loop
Разница между браузером и Node.js:
- Браузеры обычно имеют одну очередь микротаск
- Node.js разделяет
process.nextTick
и Promise очереди
Практическое значение
-
Порядок выполнения:
- Микротаски всегда между синхронным кодом и макротасками
- Важно для согласованности состояния приложения
-
Производительность:
- Избыток микротаск может задержать I/O операции
- Макротаски лучше для тяжелых задач
-
Отладка:
- Понимание порядка помогает находить race conditions
Резюмируем
- Приоритет выполнения: Микротаски > Макротаски
- Использование:
- Микротаски - для срочных асинхронных операций
- Макротаски - для менее критичных задач
- Главное правило: Event Loop обрабатывает все микротаски перед переходом к следующей макротаске
- Особенности Node.js:
process.nextTick
имеет наивысший приоритет
- Отдельные очереди для разных типов задач
Понимание этих различий критично для написания корректного асинхронного кода и предотвращения тонких ошибок.