Skip to main content

Синхронний і асинхронний код

Синхронний код виконується строго по порядку: наступна операція не почнеться, доки не завершиться попередня. Асинхронний код дозволяє програмі працювати далі, не чекаючи на завершення довгих операцій, як-от мережеві запити чи таймери.

Теорія

TL;DR

  • Синхронно означає «по порядку і блокуюче»: кожен рядок чекає на попередній.
  • Асинхронно означає «неблокуюче»: довга операція передається зовнішньому API, а код іде далі.
  • JavaScript має один потік (single thread), але завдяки event loop працює асинхронно.
  • Готовий результат потрапляє в чергу завдань і виконується, коли звільниться стек викликів (call stack).
  • Асинхронність реалізують callbacks, Promises, async/await та обробники подій.

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

javascript
console.log('1'); setTimeout(() => { console.log('2'); // runs later }, 1000); console.log('3');

Вивід:

javascript
1 3 2

Чому так:

  • setTimeout - асинхронна операція, вона планується на майбутнє.
  • JavaScript не чекає на її завершення, а йде далі.
  • Коли таймер спрацює, функція потрапить у чергу подій (event queue) і виконається пізніше, щойно звільниться стек викликів.

Синхронне виконання

javascript
console.log('1'); console.log('2'); console.log('3');

Вивід:

javascript
1 2 3

Усе виконується построково: наступна команда не почнеться, доки не завершиться попередня. Це і є синхронне виконання. Схематично:

javascript
[ Завдання 1 ] -> [ Завдання 2 ] -> [ Завдання 3 ]

Поки одна операція виконується, інші чекають.

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

JavaScript має один потік виконання, але завдяки event loop (циклу подій) може працювати асинхронно та неблокуюче.

  • Довгі операції (наприклад, fetch, setTimeout, I/O) передаються у зовнішні API середовища (браузера або Node.js).
  • JavaScript продовжує виконувати решту коду.
  • Коли операцію завершено, результат повертається у чергу колбеків і виконується пізніше.

Схематично:

javascript
[ Завдання 1 (асинхронне) ] -> [ Завдання 2 ] | (результат повернеться пізніше)

Реальні приклади

СитуаціяСинхронний кодАсинхронний код
Читання файлуJavaScript чекає, доки файл повністю прочитаєтьсяJavaScript віддає задачу API і працює далі
Запит на серверКод «заморожується» до відповідіКод іде далі, відповідь обробляється пізніше
Цикл на мільйон ітерацій«Підвішує» інтерфейсВиконується у фоні (через Web Worker або асинхронно)

Чим реалізується асинхронність

МеханізмПриклад
Callbacks (колбеки)setTimeout(() => {...}, 1000)
Promisesfetch('/data').then(...)
async / awaitconst data = await fetch('/data')
Обробники подійbutton.addEventListener('click', ...)

Приклад справжньої асинхронності з fetch:

javascript
console.log('Start'); fetch('https://api.example.com/user') .then(res => res.json()) .then(data => console.log('Response received:', data)); console.log('End');

Вивід:

javascript
Start End Response received: {...}

Поки сервер відповідає, JavaScript не чекає, а йде далі і повертається до колбека тоді, коли дані готові.

Підсумок

ВідмінністьСинхронний кодАсинхронний код
ВиконанняПослідовно, блокуючеЧерез події, неблокуюче
ЗатримкиБлокують програмуНе заважають виконанню
Використовується дляПростих і коротких операційЗапитів, таймерів, файлів, API
Прикладconsole.log()setTimeout(), fetch()
МеханізмСтек викликівEvent loop і черги завдань

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

  • Вважати, що асинхронний код виконується «паралельно» в окремому потоці. У JavaScript потік один, паралелізм дає середовище, а не сам рушій.
  • Очікувати, що setTimeout(fn, 0) виконає fn негайно: колбек усе одно чекає, доки звільниться стек викликів.
  • Записувати результат .then() у зовнішню змінну і читати її наступним рядком: там ще буде undefined.
  • Ставити важкий синхронний цикл поруч з асинхронним кодом: він блокує event loop, тому таймери та відповіді мережі «зависають».
  • Плутати await із блокуванням усієї програми: await призупиняє лише поточну async-функцію, а не весь потік.

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

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

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