Есть NodeJS,
Не пойму как сделать архитектуру правильную, многие действия являются асинхронными и как уследить за всем что бы не городить кучу колбэков и тесты запускать.
Допустим имеется класс-наблюдающий за чем-либо, этот класс выполняет функцию получения данных и передачу в нужное действие классом обработчиком, класс-обработчик выполняет какие-либо проверки и делает запись в БД. Вся эта связка усложняется асинхронными запросами.
Проблема в том, что иногда требуется определенная последовательность, да можно использовать async от Node. Но это не решение, проблема явно в архитектуре.
P.S. Да я знаю, что для работы с БД нужен дополнительный слой, но в данном примере вопрос не об этом и думаю можно обойтись без него.
class Watcher{
get EventEmitter() { return this._eventEmitter; }
constructor(){
}
DataReceived(data){
...
this._eventEmitter.emit('dataReceived',data);
}
}
class Worker{
get Watcher() { return this._watcher; }
get Database() { return this._database; }
constructor(){
this._database = orm.connect(....);
this._watcher = new Watcher();
this._watcher.EventEmitter.on('dataReceived', function(data) {
this.ProcessReceivedData(data);
}
ProcessReceivedData(data) {
var self = this;
this._database.models.A.find(... , function(err,data){
if (data.length > 1) {
self._database.models.B.create({...}, function(err,data) { });
}else{
self._database.models.B.update({...}, function(err,data) { });
}
}
}
}
тест
it('Should create record in DB', function (done) {
var Wkr = new Worker();
Wkr.Watcher.DataReceived("something"); //инсценируем отправку данных
//Проверяем есть ли запись, но она с вероятностью 99% не успеет создаться
//поскольку обращение к базе не дожидается ответа
Wkr.Database.models.Device.get(1, function (e, d) {
should.exist(d);
done();
});
});
});
И как теперь протестировать что создалась ли запись и/или обновилась?
Да можно создать событие и эмитеть типа того, что ниже. Но мы получим дублирование когда.
self._database.models.B.create({...}, function(err,data) { self.emitter.emit('onProcessedData') });
...
self._database.models.B.update({...}, function(err,data) { self.emitter.emit('onProcessedData') });
Вобщем что то я запутался...