Що означає "неблокуючий код"?
1. Що означає "блокуючий код"
"Блокуючий" - це такий код, який не відпускає основний потік (main thread), поки не завершиться.
Поки операція виконується, JavaScript не може робити нічого іншого: не обробляти кліки, не перемальовувати інтерфейс, не запускати наступні функції.
Приклад (блокуючий код):
// Імітація довгого розрахунку
function heavyCalculation() {
const start = Date.now();
while (Date.now() - start < 3000) {} // чекаємо 3 секунди
console.log("Розрахунок завершено");
}
console.log("Початок");
heavyCalculation();
console.log("Кінець");Результат:
Початок
(зависає на 3 секунди)
Розрахунок завершено
КінецьУсе завмерло на 3 секунди - інтерфейс "замерз", сервер не відповідає. Це blocking code.
2. Що означає "неблокуючий код"
"Неблокуючий" - це такий код, який не зупиняє виконання потоку, а делегує тривалі операції (I/O, мережа, таймери, файли) і продовжує виконання інших завдань.
Приклад (неблокуючий):
console.log("Початок");
setTimeout(() => {
console.log("Минула 1 секунда");
}, 1000);
console.log("Кінець");Що відбувається:
- JS викликає
setTimeout- передає завдання браузеру (Web API). - Продовжує виконання (
"Кінець"одразу друкується). - Через 1 сек callback повертається у чергу завдань і виконується.
Результат:
Початок
Кінець
Минула 1 секундаКод не блокував потік. JS вільно обробляв інші події, поки таймер "працював у фоні".
3. Чому це важливо в JavaScript
JavaScript - однопотоковий, тобто:
- у кожен момент часу виконується тільки один шматок коду;
- якщо один шматок "завис" - решта чекає.
Щоб уникнути "зависань", JS використовує:
- асинхронність (
setTimeout,fetch,async/await); - зовнішні API (Web APIs / libuv thread pool);
- event loop, щоб повернути результат, коли він готовий.
4. Приклади неблокуючих операцій
| Тип операції | Приклад | Що робить |
|---|---|---|
| Таймери | setTimeout, setInterval | виконуються пізніше |
| Мережа | fetch, XMLHttpRequest | чекають відповідь від сервера у фоні |
| Файли (Node.js) | fs.readFile | читають диск асинхронно |
| Запити до БД | db.query | чекають результат без блокування |
| Слухачі подій | addEventListener('click') | спрацьовують при події |
| Проміси | Promise, async/await | відкладають виконання до завершення операції |
5. Приклад різниці в Node.js
Блокуючий варіант
const fs = require('fs');
console.log('Читання файлу...');
const data = fs.readFileSync('large.txt', 'utf8'); // блокує потік
console.log('Файл прочитано:', data.length);Поки файл читається, сервер не обслуговує інші запити.
Неблокуючий варіант
const fs = require('fs');
console.log('Читання файлу...');
fs.readFile('large.txt', 'utf8', (err, data) => {
console.log('Файл прочитано:', data.length);
});
console.log('Інший код виконується...');Node.js віддає завдання системі (I/O) і продовжує виконання. Коли файл готовий, callback повертається через event loop.
6. Чому "неблокуючий" не дорівнює "паралельний"
Це часта помилка на співбесідах:
"Неблокуючий код" не означає, що все працює паралельно.
JS усе ще виконує один callback за раз, але не витрачає час даремно, чекаючи I/O. У цей час рушій обробляє інші завдання - тому й виникає враження паралельності.
7. Коротко: блокуючий vs неблокуючий
| Тип | Що робить | Приклад | Наслідок |
|---|---|---|---|
| Блокуючий | Зупиняє потік, поки не завершиться | fs.readFileSync() | Зависає UI / сервер |
| Неблокуючий | Делегує завдання, продовжує роботу | fs.readFile() / fetch() | Висока відгукливість |
Резюме
Неблокуючий код - це спосіб писати програми, де тривалі операції (I/O, мережа, таймери) виконуються асинхронно, не заважаючи основній логіці і не "заморожуючи" потік.
Він лежить в основі:
- асинхронності JS (
callbacks,promises,async/await); - продуктивності Node.js;
- плавності інтерфейсів у браузері.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.