Вопрос проверяет понимание асинхронного выполнения в JavaScript, в частности, как промисы и их обработчики взаимодействуют с Event Loop и очередями микрозадач.
Чтобы понять, когда выполняется Promise.then, нужно разобраться в двух ключевых концепциях JavaScript: Event Loop и очередях задач. JavaScript является однопоточным, и Event Loop управляет порядком выполнения кода, используя очередь макрозадач (например, события, setTimeout) и очередь микрозадач (для промисов).
Когда промис разрешается (fulfilled или rejected), все его обработчики .then, .catch или .finally помещаются в очередь микрозадач. Event Loop работает по циклу: он выполняет текущую синхронную задачу (макрозадачу) до конца, затем проверяет очередь микрозадач. Если в ней есть задачи, он выполняет их все, одну за другой, пока очередь не опустеет. Только после этого Event Loop берёт следующую макрозадачу из своей очереди.
Рассмотрим код, который наглядно показывает приоритет микрозадач:
console.log('1. Синхронный старт');
setTimeout(() => {
console.log('4. Макрозадача из setTimeout');
}, 0);
Promise.resolve()
.then(() => {
console.log('3. Микрозадача из Promise.then');
});
console.log('2. Синхронный конец');
Вывод будет:
1. Синхронный старт
2. Синхронный конец
3. Микрозадача из Promise.then
4. Макрозадача из setTimeout
Объяснение:
setTimeout помещается в очередь макрозадач..then попадает в очередь микрозадач.setTimeout (выводит 4).Этот механизм критически важен для предсказуемости асинхронного кода. Он гарантирует, что обработка промисов (например, обновление состояния после fetch-запроса) происходит как можно скорее, до любых отложенных макрозадач. Это используется в современных фреймворках (React, Vue) для планирования обновлений UI и в библиотеках для управления асинхронными потоками.
Вывод: Обработчик Promise.then выполняется как микрозадача сразу после завершения текущего синхронного кода и перед следующей макрозадачей, что обеспечивает высокий приоритет и детерминированный порядок выполнения асинхронных операций.