Skip to main content

Асинхронність у JavaScript

Асинхронність у JavaScript, це механізм, який дозволяє виконувати задачі без блокування основного потоку (main thread). Простіше кажучи, JavaScript може не чекати завершення довгих операцій (наприклад, запитів до сервера, читання файлів або таймерів), а продовжувати виконувати решту коду і обробити результат пізніше, коли він буде готовий.

Теорія

TL;DR

  • JavaScript, це однопотокова мова: код виконується послідовно, по одній задачі за раз.
  • Асинхронність потрібна, щоб не «заморожувати» сторінку під час довгих операцій.
  • Асинхронність, це не паралельність, а механізм планування задач.
  • Реалізована вона через Event Loop, стек викликів, Web API і чергу задач.
  • Основні способи роботи: колбеки, проміси, async/await.
  • await зупиняє виконання всередині функції, але не блокує потік.

Швидкий приклад

javascript
console.log('1'); setTimeout(() => { console.log('2'); // виконається пізніше }, 1000); console.log('3');

Вивід:

javascript
1 3 2

Так відбувається тому, що setTimeout, це асинхронна операція: вона «стає в чергу» і виконується після основного коду, через 1 секунду.

Синхронний код і блокування

javascript
console.log('1'); alert('Зачекайте...'); // блокує виконання console.log('2');

Поки користувач не закриє alert, програма зупинена, це синхронний код. Саме таку поведінку і усуває асинхронність: довга операція не тримає основний потік.

Як це працює під капотом

Асинхронність у JS реалізована через Event Loop (цикл подій).

  1. Основний код виконується у стеку викликів (Call Stack).
  2. Асинхронні операції (таймери, fetch, події тощо) передаються у Web API (API браузера або Node.js).
  3. Коли операція завершена, колбек потрапляє в чергу задач (Callback Queue).
  4. Event Loop перевіряє, чи вільний стек, і якщо так, бере задачу з черги та виконує її.

Таким чином, асинхронність, це не «паралельність», а механізм планування задач.

Основні способи роботи з асинхронністю

ПідхідПрикладОсобливості
Callbacks (колбеки)setTimeout(() => {...}, 1000)Старий, незручний (callback hell)
Promises (проміси)fetch(...).then(...)Сучасніший, читабельніший
async / awaitconst data = await fetch(...)Найзручніший синтаксис

Приклад з Promise:

javascript
fetch('https://api.example.com/user') .then(response => response.json()) .then(data => console.log(data)) .catch(err => console.error(err));

fetch повертає Promise, тобто обіцянку, що результат буде отриманий у майбутньому, і його можна обробити через .then().

Приклад з async/await:

javascript
async function loadUser() { try { const res = await fetch('https://api.example.com/user'); const user = await res.json(); console.log(user); } catch (e) { console.error(e); } } loadUser();

await «зупиняє» виконання всередині функції, доки проміс не виконається, але не блокує потік. Асинхронність зберігається.

Типові асинхронні операції в JS

  • setTimeout, setInterval
  • fetch() (мережеві запити)
  • Робота з файлами в Node.js (fs.promises)
  • Події (addEventListener)
  • WebSocket, IndexedDB, Web Workers тощо

Підсумок термінів

ТермінЩо означає
АсинхронністьВиконання задач «у фоні» без блокування основного потоку
Event LoopМеханізм, який керує чергою задач
Callback QueueЧерга готових до виконання задач
PromiseОб'єкт, що представляє результат асинхронної операції
async / awaitЗручний синтаксис для роботи з промісами

Типові помилки

  • Плутати асинхронність із багатопотоковістю: другого потоку для вашого коду не з'являється, змінюється лише порядок виконання.
  • Вважати, що setTimeout(fn, 1000) гарантує рівно 1 секунду: це мінімальна затримка, задача чекатиме, доки звільниться стек.
  • Блокувати основний потік важким синхронним циклом і дивуватися, що асинхронні колбеки не спрацьовують вчасно.
  • Забувати про обробку помилок: проміс без .catch() або try...catch дає unhandled rejection.
  • Змішувати колбеки і проміси в одній ланцюжковій логіці замість того, щоб привести все до async/await.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.