Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Архитектура Node.js
Node.js — это асинхронная, событийно-ориентированная платформа для выполнения JavaScript на сервере. Её работа основана на трёх ключевых компонентах:
1. Event Loop (Цикл событий)
Event Loop — сердце Node.js. Это бесконечный цикл, который проверяет наличие задач и выполняет их.
// Упрощённая модель Event Loop
while (eventLoop.waitForTask()) {
const macrotask = eventLoop.nextMacrotask();
if (macrotask) macrotask();
const microtasks = eventLoop.nextMicrotasks();
microtasks.forEach(task => task());
}
Event Loop проходит несколько фаз:
- Timers — выполнение callbacks из setTimeout/setInterval
- I/O callbacks — асинхронные операции файловой системы, сети
- Check — setImmediate callbacks
- Close — закрытие соединений
2. libuv (Асинхронная I/O библиотека)
libuv предоставляет асинхронную обработку I/O операций через thread pool:
// Пример асинхронной операции
import fs from 'fs';
fs.readFile('file.txt', 'utf-8', (err, data) => {
if (err) console.error(err);
else console.log(data);
});
console.log('Это выполнится раньше!');
При чтении файла:
- Задача добавляется в очередь libuv
- Рабочий поток из pool'а выполняет I/O
- После завершения callback попадает в очередь Event Loop
- Event Loop выполняет callback
3. V8 JavaScript Engine
V8 компилирует и выполняет JavaScript код. Он использует:
- JIT компиляцию для оптимизации горячего кода
- Garbage Collection для управления памятью
// V8 оптимизирует этот код
function add(a, b) {
return a + b;
}
// После нескольких вызовов V8 создаст machine code для этой функции
for (let i = 0; i < 1000000; i++) {
add(i, i + 1);
}
Порядок выполнения кода
Важно понимать микротаски vs макротаски:
console.log('1'); // Синхронный код
setTimeout(() => console.log('2'), 0); // Макротаска (Timers)
Promise.resolve()
.then(() => console.log('3')); // Микротаска (Microtask Queue)
setImmediate(() => console.log('4')); // Макротаска (Check фаза)
console.log('5'); // Синхронный код
// Результат: 1, 5, 3, 2, 4
Порядок выполнения:
- Всё синхронный код (1, 5)
- Все микротаски: Promises, queueMicrotask (3)
- Первый макротаск: setTimeout (2)
- Микротаски после (если есть)
- Следующий макротаск: setImmediate (4)
Non-blocking I/O
Главное преимущество Node.js — неблокирующие операции:
// ❌ Блокирующий код (избегать!)
const data = fs.readFileSync('file.txt', 'utf-8');
console.log(data); // Ждёт, пока файл прочитается
// ✅ Неблокирующий код
fs.readFile('file.txt', 'utf-8', (err, data) => {
console.log(data);
});
console.log('Продолжаем дальше'); // Выполнится сразу
Это позволяет обрабатывать тысячи параллельных операций на одном потоке.
Управление памятью
Node.js использует V8 Garbage Collection:
// Утечки памяти возникают при:
const cache = {}; // Растёт бесконечно
function addToCache(key, value) {
cache[key] = value; // Никогда не удаляется
}
// ✅ Правильно: используй LRU Cache или установи лимит
import LRU from 'lru-cache';
const cache = new LRU({ max: 100 });
Производительность
- Node.js оптимален для I/O-heavy операций (API, базы данных)
- Не подходит для CPU-intensive задач (обработка видео, расчёты)
- Для CPU-heavy используй Worker Threads или native modules