Однопотоковість JS
1. Що означає "single-threaded"
Single-threaded (однопотоковий) означає, що весь JavaScript-код виконується в одному потоці, на одному "виконавці" (main thread).
Тобто:
- одночасно може виконуватися лише одна інструкція JS;
- немає паралельного виконання коду (на відміну від C++, Java, Go);
- якщо одна функція зайняла потік, весь інший код чекає на її завершення.
2. Чому JS таким зробили
JavaScript створювався для браузера, щоб:
- безпечно взаємодіяти з DOM (щоб не було конфліктів при одночасних змінах);
- бути простим, передбачуваним і не вимагати складної синхронізації (м'ютексів, локів тощо).
Ідея: "один потік = один власник DOM = жодних гонок даних".
3. Як це працює на практиці
Приклад
console.log('A');
setTimeout(() => console.log('B'), 0);
console.log('C');Результат:
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 - це "координатор", який стежить за тим, щоб основний потік не простоював.
Механізм:
- JS виконує код зі стека викликів (основний потік).
- Коли трапляється асинхронна операція, вона йде у зовнішній Web API (мережеві запити, таймери, проміси).
- Після завершення ці операції потрапляють у чергу задач (task queue).
- 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 Threads | Node.js | Паралельне виконання CPU-bound задач |
| Async/await | Всюди | Робить I/O операції неблокувальними |
| Виведення в WebAssembly | Всюди | Складні розрахунки - у нативний код |
8. Проста аналогія
Уяви кафе:
- Один кухар (JS-потік).
- Кілька офіціантів і кур'єрів (Web API, async задачі).
- Кухар готує одну страву за раз, але офіціанти продовжують працювати.
- Коли готово, офіціанти повертають замовлення кухарю (event loop приносить задачу назад).
Коротке резюме
| Термін | Значення |
|---|---|
| Single-threaded | JS виконує код в одному потоці |
| Асинхронність | Реалізована через зовнішні API та event loop |
| Event loop | Координує виконання асинхронних задач |
| Блокувальні операції | Можуть "заморозити" UI/сервер |
| Рішення | async/await, Workers, WebAssembly |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.