Skip to main content

Однопотоковість JS

1. Що означає "single-threaded"

Single-threaded (однопотоковий) означає, що весь JavaScript-код виконується в одному потоці, на одному "виконавці" (main thread).

Тобто:

  • одночасно може виконуватися лише одна інструкція JS;
  • немає паралельного виконання коду (на відміну від C++, Java, Go);
  • якщо одна функція зайняла потік, весь інший код чекає на її завершення.

2. Чому JS таким зробили

JavaScript створювався для браузера, щоб:

  • безпечно взаємодіяти з DOM (щоб не було конфліктів при одночасних змінах);
  • бути простим, передбачуваним і не вимагати складної синхронізації (м'ютексів, локів тощо).

Ідея: "один потік = один власник DOM = жодних гонок даних".

3. Як це працює на практиці

Приклад

javascript
console.log('A'); setTimeout(() => console.log('B'), 0); console.log('C');

Результат:

javascript
A C B

Чому:

  • JS виконує console.log('A'), потім setTimeout(...), потім console.log('C');
  • setTimeout - це асинхронна операція, вона йде у веб-API браузера (або Node);
  • коли таймер закінчився, callback повертається в чергу задач (task queue);
  • event loop додає callback назад в основний потік, коли той звільниться.

4. Що робить event loop

Event Loop - це "координатор", який стежить за тим, щоб основний потік не простоював.

Механізм:

  1. JS виконує код зі стека викликів (основний потік).
  2. Коли трапляється асинхронна операція, вона йде у зовнішній Web API (мережеві запити, таймери, проміси).
  3. Після завершення ці операції потрапляють у чергу задач (task queue).
  4. Event loop перевіряє: якщо стек порожній, бере наступну задачу з черги і запускає її.

Таким чином, JS виглядає "асинхронним", але під капотом все одно однопотоковий.

5. Але ж браузер і Node.js роблять багато речей одночасно?

Так, але не сам JS!

Асинхронність реалізована через зовнішні API, які працюють в інших потоках чи процесах:

  • таймери (setTimeout, setInterval) обробляються в окремій підсистемі;
  • мережеві запити (fetch, XMLHttpRequest) обробляються на рівні браузера;
  • файлова система, сокети (у Node.js) виконуються через пул потоків libuv;
  • після завершення ці задачі повертаються в основний JS-потік.

Сам рушій JS (наприклад, V8) - однопотоковий. А середовище виконання (Browser API, Node.js) - багатопотокове.

6. Що блокує однопотоковий JS

Оскільки все виконується в одному потоці:

  • довгі цикли (for, while);

  • великі JSON.parse;

  • рекурсивні обчислення;

  • синхронні операції з файлами (у Node.js)

  • блокують event loop, і інтерфейс чи сервер "зависають".

7. Як вирішують проблему "single-threaded" у JS

ПідхідДе використовуєтьсяЩо робить
Web WorkersБраузерЗапускають JS-код в окремому потоці без доступу до DOM
Worker ThreadsNode.jsПаралельне виконання CPU-bound задач
Async/awaitВсюдиРобить I/O операції неблокувальними
Виведення в WebAssemblyВсюдиСкладні розрахунки - у нативний код

8. Проста аналогія

Уяви кафе:

  • Один кухар (JS-потік).
  • Кілька офіціантів і кур'єрів (Web API, async задачі).
  • Кухар готує одну страву за раз, але офіціанти продовжують працювати.
  • Коли готово, офіціанти повертають замовлення кухарю (event loop приносить задачу назад).

Коротке резюме

ТермінЗначення
Single-threadedJS виконує код в одному потоці
АсинхронністьРеалізована через зовнішні API та event loop
Event loopКоординує виконання асинхронних задач
Блокувальні операціїМожуть "заморозити" UI/сервер
Рішенняasync/await, Workers, WebAssembly

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

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

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