Skip to main content

Що означає термін non-blocking

Термін «non-blocking» (неблокуючий) означає, що виконання програми не зупиняється, поки очікується завершення довгої операції, наприклад мережевого запиту, таймера або читання файлу. Простіше кажучи, non-blocking, це «не чекай, продовжуй виконувати інший код».

Теорія

TL;DR

  • Неблокуючий код не призупиняє основний потік виконання.
  • Поки асинхронна операція працює «у фоні», JS виконує інші задачі.
  • Реалізовано це через однопотокову модель, Event Loop, асинхронні API і черги задач.
  • setTimeout, fetch, fs.readFile, це неблокуючі операції.
  • Важкий синхронний цикл, навпаки, блокує все, включно з інтерфейсом.
  • Node.js побудований навколо non-blocking I/O, тому один процес обслуговує багато запитів.

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

javascript
console.log('A'); setTimeout(() => { console.log('B'); }, 2000); console.log('C');

Вивід:

javascript
A C B

setTimeout, це non-blocking операція: вона не зупиняє виконання програми, а планує виклик колбека пізніше.

Блокуючий і неблокуючий код

Блокуючий варіант:

javascript
function sleep(ms) { const start = Date.now(); while (Date.now() - start < ms) {} // блокує потік } console.log('A'); sleep(2000); console.log('B');

Вивід (через 2 секунди):

javascript
A B

Усе «зависло» на 2 секунди: доки працює sleep(), ні інтерфейс, ні інші скрипти не виконуються. Це blocking код.

Неблокуючий варіант із setTimeout (див. швидкий приклад вище) дає A, C, B: рядок C виконується одразу, а B чекає своєї черги, не займаючи потік.

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

Неблокуюча поведінка досягається за рахунок:

  1. однопотокової моделі JS, де все проходить через Event Loop;
  2. асинхронних API (браузерних або Node.js);
  3. черг задач (Callback Queue), де чекають готові результати.

JS відправляє операцію (наприклад, fetch) у зовнішній API і не чекає, а виконує код далі. Коли результат готовий, колбек повертається в чергу, і Event Loop виконає його, щойно стек викликів звільниться.

Non-blocking у Node.js

Node.js побудований навколо non-blocking I/O (вводу та виводу). Це означає:

  • операції з файлами, мережею, базою даних є асинхронними;
  • замість очікування результату Node продовжує обслуговувати інші запити.
javascript
const fs = require('fs'); console.log('Start'); fs.readFile('file.txt', 'utf8', (err, data) => { console.log('File has been read'); }); console.log('End');

Вивід:

javascript
Start End File has been read

Читання файлу тут non-blocking: Node не чекає його завершення, а виконує решту коду.

Чому це важливо

ПідхідЩо робитьНедолік
BlockingВиконує операції строго послідовно«Підвішує» потік, гальмує інтерфейс
Non-blockingДозволяє виконувати інші задачі під час очікуванняТреба вміти працювати з колбеками та промісами

Асинхронність і неблокуюча поведінка роблять JS чуйним та ефективним, особливо в браузері й у серверних застосунках.

Життєва аналогія: уявіть офіціанта в кафе.

  • Блокуючий підхід: він стоїть і чекає, поки приготують замовлення клієнта, і лише потім приймає наступне.
  • Неблокуючий підхід: він передає замовлення на кухню і обслуговує інших клієнтів, поки страва готується.

JavaScript поводиться як другий офіціант.

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

ТермінЗначення
BlockingВиконання зупиняється, доки операція не завершиться
Non-blockingВиконання продовжується, а результат обробляється пізніше
РеалізаціяЧерез Event Loop, асинхронні колбеки, проміси
ПеревагаНе «заморожує» потік, швидкий відгук

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

  • Вважати, що non-blocking означає багатопотоковість: код усе одно виконується в одному потоці.
  • Писати власний sleep() на циклі while замість await new Promise(r => setTimeout(r, ms)).
  • Використовувати синхронні варіанти API Node.js (fs.readFileSync) у коді, що обслуговує запити.
  • Робити важкі обчислення в основному потоці: навіть асинхронний код не врятує від блокування.
  • Думати, що await блокує потік: він призупиняє лише свою async-функцію, а потік залишається вільним.

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

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

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