Как распределяются по очереди задач синхронный код
Разбор вопроса «Как распределяются по очереди задач синхронный код» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.
Вопрос
Как распределяются по очереди задач синхронный код
Профессия
Frontend Developer
Что хочет услышать интервьюер
Интервьюер хочет убедиться, что кандидат понимает базовый принцип работы Event Loop и очередности выполнения задач в JavaScript, включая разницу между синхронным и асинхронным кодом.
Ключевые тезисы
- Синхронный код выполняется последовательно, строка за строкой, в порядке его написания.
- Каждая синхронная задача попадает в Call Stack (стек вызовов) и выполняется немедленно, блокируя дальнейшее выполнение кода до своего завершения.
- Синхронные операции имеют приоритет над асинхронными, так как они не требуют ожидания (например, API-запросов или таймеров).
- После выполнения синхронного кода Event Loop проверяет очередь задач (Task Queue) и начинает выполнять асинхронные задачи (например, колбэки из setTimeout или Promise).
Подробный ответ
Синхронный код в JavaScript выполняется последовательно, строка за строкой, в том порядке, в котором он написан. Каждая синхронная задача попадает в Call Stack (стек вызовов) и выполняется немедленно. Call Stack — это структура данных, которая отслеживает текущий контекст выполнения. Когда функция вызывается, она добавляется в стек, а когда завершает выполнение — удаляется из него. Синхронный код блокирует дальнейшее выполнение программы до своего завершения, так как он не требует ожидания внешних событий, таких как API-запросы или таймеры. После завершения выполнения синхронного кода Event Loop начинает проверять очередь задач (Task Queue) и обрабатывать асинхронные задачи, такие как колбэки из setTimeout или Promise. Event Loop — это механизм, который управляет выполнением асинхронного кода, проверяя, пуст ли Call Stack, и перемещая задачи из очереди в стек для выполнения. Синхронный код имеет приоритет над асинхронным, так как он выполняется немедленно, не требуя ожидания.
Практические примеры
Пример 1
Синхронный код блокирует выполнение асинхронного.
console.log('Начало');
setTimeout(() => console.log('Таймер'), 0);
console.log('Конец');
// Вывод: Начало, Конец, ТаймерЗдесь синхронный код выполняется первым, а setTimeout, хотя и имеет задержку 0, попадает в очередь задач и выполняется после завершения синхронного кода.
Пример 2
Пример с ошибкой в синхронном коде.
console.log('Начало');
throw new Error('Ошибка!');
console.log('Конец');
// Вывод: Начало, затем выбрасывается ошибка, и 'Конец' не выполняется.Если в синхронном коде возникает ошибка, выполнение кода прекращается, и асинхронные задачи не выполняются, пока ошибка не будет обработана.
Частые ошибки
- Ошибка: Непонимание того, что синхронный код всегда выполняется перед асинхронным, даже если асинхронный код имеет нулевую задержку.
- Ошибка: Игнорирование того, что ошибка в синхронном коде может полностью остановить выполнение программы, включая асинхронные задачи.
Связанные темы
- Event Loop и его роль в асинхронном выполнении кода.
- Разница между микротасками (microtasks) и макротасками (macrotasks) в контексте Event Loop.
- Работа с ошибками в JavaScript и использование try/catch для обработки исключений.
Follow-up вопросы
Что такое Call Stack и как он работает?
Уровень: basic
Call Stack — это структура данных, которая хранит информацию о вызовах функций. Когда функция вызывается, она помещается в стек, а когда завершается — удаляется из него. Синхронный код выполняется в порядке LIFO (Last In, First Out).
Как Event Loop обрабатывает асинхронный код после выполнения синхронного?
Уровень: intermediate
Event Loop проверяет Call Stack и Task Queue. Если Call Stack пуст, он берет первую задачу из Task Queue (например, колбэк из setTimeout) и помещает ее в Call Stack для выполнения. Это гарантирует неблокирующее выполнение асинхронного кода.
Может ли синхронный код блокировать Event Loop? Приведите пример.
Уровень: intermediate
Да, например, бесконечный цикл или тяжелые вычисления в синхронном коде заблокируют Event Loop, так как Call Stack не освободится. Это приведет к «зависанию» интерфейса и невозможности выполнения асинхронных задач.
Как микротаски (microtasks) отличаются от макротасок (macrotasks) в контексте Event Loop?
Уровень: advanced
Микротаски (например, колбэки Promise.then) выполняются сразу после текущей синхронной задачи, до перехода к макротаскам (setTimeout, setInterval). Они имеют приоритет и обрабатываются в отдельной очереди — Microtask Queue.
Что произойдет, если в синхронном коде выбросить ошибку? Как это повлияет на очередь задач?
Уровень: intermediate
Синхронная ошибка прервет выполнение текущего блока кода, и Call Stack очистится. Event Loop продолжит работу, но последующий синхронный код после ошибки не выполнится. Асинхронные задачи из очереди обработаются, если ошибка не была перехвачена.
console.log() - синхронная или асинхронная операция
Разбор вопроса «console.log() - синхронная или асинхронная операция» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.
Что такое дженерики 😎
Дженерики в TypeScript позволяют писать переиспользуемый код и сохранять связь между входными и выходными типами. На странице разбираем, как объяснить их на интервью, где они полезны и когда они только усложняют код.