🧱 Суть
queueMicrotask() позволяет отложить выполнение функции до конца текущего синхронного кода, но выполнить её раньше обычных отложенных задач (setTimeout).
📦 Проблема
Иногда нужно выполнить действие после завершения текущих обновлений состояния или синхронной логики.
Например:
appStore.closeModal();
navigate('/');Если closeModal() вызывает изменение состояния, React может ещё не успеть завершить обновление, а navigate() уже выполнится.
✅ Решение
Использовать queueMicrotask():
queueMicrotask(() => navigate('/'));Теперь переход произойдёт после завершения текущего стека вызовов.
💻 Код
Как работает Event Loop
Синхронный код
Выполняется сразу:
console.log('A');
console.log('C');Microtask Queue
Сюда попадают:
queueMicrotaskPromise.thenMutationObserver
Они выполняются после текущего кода.
Macrotask Queue
Сюда попадают:
setTimeoutsetInterval- события браузера
Они выполняются позже.
Пример
console.log('A');
queueMicrotask(() => {
console.log('B');
});
console.log('C');Результат:
A
C
BB выполнится после основного кода, но раньше:
setTimeout(() => console.log('D'), 0);queueMicrotask vs setTimeout
setTimeout
setTimeout(() => {
navigate('/');
}, 0);Создаёт macrotask.
Минус:
- выполнится позже;
- может ждать очередь браузерных событий.
queueMicrotask
queueMicrotask(() => {
navigate('/');
});Создаёт microtask.
Плюсы:
- выполняется быстрее;
- подходит для последовательных обновлений состояния;
- сохраняет текущий контекст выполнения.
Аналог через Promise
То же самое можно написать:
Promise.resolve().then(() => navigate('/'));Но для одного отложенного действия читаемее:
queueMicrotask(() => navigate('/'));Пример с React
Проблемный вариант:
const logout = () => {
appStore.closeModal();
navigate('/');
};Возможная проблема:
closeModal()
↓
изменение состояния
↓
React готовит обновление
navigate()
↓
переход выполняется раньше завершения обновленияВариант с queueMicrotask:
const logout = () => {
appStore.closeModal();
queueMicrotask(() => {
navigate('/');
});
};Порядок:
closeModal()
↓
текущий синхронный код заканчивается
↓
microtask queue
↓
navigate()🎯 Вывод
queueMicrotask()откладывает выполнение до конца текущего тика.- Это быстрее и точнее, чем
setTimeout(..., 0). - Используется, когда нужно дождаться завершения текущих синхронных операций.
- Хорошо подходит для случаев с React state updates, MobX и последовательными действиями.