Ответ
В Node.js контексте управление состоянием имеет свою специфику. Вот подходы, которые я использовал:
1. EventEmitter для реактивного состояния:
const EventEmitter = require('events');
class ApplicationState extends EventEmitter {
constructor() {
super();
this._state = {
connectedUsers: 0,
serverStatus: 'running',
lastError: null
};
}
setState(updates) {
this._state = { ...this._state, ...updates };
this.emit('stateChanged', this._state);
}
getState() {
return { ...this._state };
}
}
// Использование
const appState = new ApplicationState();
appState.on('stateChanged', (newState) => {
console.log('State updated:', newState);
// Обновляем метрики, логируем и т.д.
});
appState.setState({ connectedUsers: 42 });
2. Finite State Machines (XState) для сложной логики:
const { Machine, interpret } = require('xstate');
const paymentMachine = Machine({
id: 'payment',
initial: 'idle',
states: {
idle: {
on: { START: 'processing' }
},
processing: {
on: {
SUCCESS: 'completed',
FAILURE: 'failed'
}
},
completed: { type: 'final' },
failed: {
on: { RETRY: 'processing' }
}
}
});
const paymentService = interpret(paymentMachine)
.onTransition((state) => {
console.log('Payment state:', state.value);
})
.start();
paymentService.send('START');
3. Shared memory для worker процессов: При использовании кластеризации или worker_threads можно использовать:
- SharedArrayBuffer для примитивных данных
- Redis как распределенное хранилище состояния
- Базы данных (PostgreSQL, MongoDB) для персистентного состояния
4. Контекст выполнения (Execution Context): Для передачи состояния через middleware цепочку в Express:
// Установка контекста
app.use((req, res, next) => {
req.context = {
requestId: uuid(),
userId: req.user?.id,
startTime: Date.now()
};
next();
});
// Использование в обработчике
app.get('/api/data', async (req, res) => {
const data = await db.query('SELECT * FROM data', {
requestId: req.context.requestId
});
res.json(data);
});
Выбор подхода зависит от требований: для простых случаев достаточно EventEmitter, для сложных бизнес-процессов — конечные автоматы, для распределенных систем — Redis.