Node.js — мощный инструмент, но у него есть принципиальные ограничения, которые важно учитывать при выборе технологии для проекта.
Проблема: Один поток выполнения блокирует цикл событий
// Плохой пример: синхронный расчет чисел Фибоначчи
function fibonacciSync(n) {
if (n <= 1) return n;
return fibonacciSync(n - 1) + fibonacciSync(n - 2);
}
app.get('/fib/:n', (req, res) => {
const result = fibonacciSync(req.params.n); // Блокирует весь сервер!
res.send({ result });
});
Что делать:
Проблема: Нет нормальной поддержки настоящих потоков
// Попытка использовать разделяемую память
const { Worker, isMainThread, SharedArrayBuffer } = require('worker_threads');
if (isMainThread) {
const buffer = new SharedArrayBuffer(16);
new Worker(__filename, { workerData: buffer });
// Сложная синхронизация, легко получить race condition
}
Альтернативы:
Примеры плохих сценариев:
Проблема: ORM в Node.js менее развиты чем в других экосистемах
// Типичный проблемный запрос в Sequelize
const results = await User.findAll({
include: [
{ model: Post, where: { status: 'published' } },
{ model: Comment, include: [Reply] }
],
where: { active: true }
});
// Генерирует неоптимальные SQL-запросы
Что делать:
Критично для:
// Проблемный код: синхронная обработка файла
app.post('/upload', (req, res) => {
const data = fs.readFileSync(req.file.path); // Блокировка!
const processed = processDataSync(data); // Еще блокировка!
res.send(processed);
});
Не подходит для:
Ограничения:
Проблема: Нужно явно реализовывать кластеризацию
// Кластеризация требует дополнительного кода
const cluster = require('cluster');
if (cluster.isMaster) {
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
require('./server');
}
Примеры:
Проблема: TypeScript — лишь надстройка, нет настоящей типизации в рантайме
interface User {
id: number;
name: string;
}
function saveUser(user: User) {
// В рантайме тип не проверяется!
db.save(user);
}
Node.js плохо подходит для:
Когда выбирать Node.js:
Лучшие альтернативы для специфичных задач: