Асинхронность в JavaScript
JS – однопоточный язык.
Он выполняет код последовательно и не может выполнять две операции одновременно внутри одного потока.
Многие операции — например, fetch, setTimeout, работа с файлами и события DOM — не могут выполняться синхронно без блокировки интерфейса. Эти операции предоставляются не самим JS, а окружением (браузером, Node.js).
Как работает асинхронность
- JavaScript вызывает функцию, которая запускает асинхронную операцию (
fetch,setTimeout, и т.д.). - Операция передаётся в окружение (Web API / Node API), где она выполняется.
- JavaScript не ждёт её завершения и продолжает выполнение остального кода.
- Когда операция завершается, окружение создаёт уведомление и помещает его в очередь.
- Event Loop извлекает уведомление из очереди и передаёт его обратно JavaScript.
- JavaScript выполняет соответствующий callback или продолжает Promise.
Такой подход позволяет не блокировать интерфейс и сохранять отзывчивость приложения.
Пример из жизни
Представим, что мы пришли в кофейню и заказали кофе. Если бы бариста работал синхронно, то он:
- взял бы заказ
- поставил кофе готовиться
- ждал бы, пока кофе приготовится
- только потом занялся бы следующим клиентом
Это было бы блокирующее поведение. Но реальность работает асинхронно:
- Бариста принимает заказ (вызов асинхронной функции)
- Передаёт заказ кофемашине (Web API)
- Даёт нам номер заказа (callback)
- Обслуживает других клиентов (неблокирующее поведение)
- Когда кофе готов, кофемашина подаёт сигнал (событие)
- Бариста вызывает номер (event loop вызывает callback)
Пример в коде
console.log("1: Начало");
// Это синхронный вызов — выполняется сразу.
setTimeout(() => {
console.log("3: Таймер сработал");
// Этот код попадёт в очередь задач и выполнится ПОТОМ,
// даже если задержка = 0 мс.
}, 0);
// JS передаёт таймер в Web API и сразу идёт дальше.
console.log("2: Конец");
// Этот вызов выполнится раньше callback из setTimeout,
// потому что основной поток не блокирован.