Синхронний та асинхронний код у Node.js
Sync vs Async в Node.js
Node.js є однопотоковим. Розуміння синхронного та асинхронного виконання є основоположним для написання продуктивного, неблокуючого коду Node.js.
Синхронний (Блокуючий)
Синхронний код блокує цикл подій — нічого іншого не виконується, поки операція не завершиться.
js
const fs = require('fs');
// БЛОКУЮЧИЙ — чекає, поки файл повністю зчитається
const data = fs.readFileSync('./file.txt', 'utf8');
console.log(data);
console.log('Це виконується після зчитування файлу');Проблема: Якщо зчитувати файл обсягом 1 ГБ, всі інші запити заблоковані!
Асинхронний (Неблокуючий)
Асинхронний код передає операцію і продовжує виконання. Callback/Promise виконується, коли операція завершується.
Callback (старий стиль)
js
const fs = require('fs');
fs.readFile('./file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
console.log('Це виконується ДО зчитування файлу!');Promises
js
const fs = require('fs').promises;
fs.readFile('./file.txt', 'utf8')
.then(data => console.log(data))
.catch(err => console.error(err));
console.log('Це виконується ДО зчитування файлу!');async/await (сучасний)
js
const fs = require('fs').promises;
async function readFile() {
try {
const data = await fs.readFile('./file.txt', 'utf8');
console.log(data);
} catch (err) {
console.error(err);
}
}
readFile();
console.log('Це виконується ДО зчитування файлу!');Що відбувається під капотом
Асинхронний I/O запит
↓
пул потоків libuv (ОС обробляє це)
↓
Цикл подій опитує на завершення
↓
Callback/Promise вирішується на головному потоціГоловний потік ніколи не блокується — він продовжує обробляти інші події.
Загальні асинхронні патерни
| Патерн | Плюси | Мінуси |
|---|---|---|
| Callbacks | Прості, універсальні | Пекло callback, важко читати |
| Promises | Ланцюгові, краща обробка помилок | Об'ємні для складних потоків |
| async/await | Читабельні, лінійний потік | Потрібен try/catch |
Правило
- Ніколи не використовуйте синхронний I/O у коді виробничого сервера (
readFileSync,writeFileSyncтощо) - Використовуйте async/await для більшості випадків
- Використовуйте
Promise.all()для виконання кількох асинхронних операцій паралельно
js
// Паралельне виконання — набагато швидше!
const [users, posts] = await Promise.all([
fetchUsers(),
fetchPosts()
]);Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.