Я делаю приложение, которое принимает сообщения с нескольких устройств. При получении сообщения запускается событие с данным сообщением:
on( "data", message => {
//doSomething
} );
Эта функция получает два типа сообщений: A и B:
Мой первый подход к этому был следующий:
const { ifElse } = require("ramda");
const evalData = ifElse(
isTypeA, // Returns true if type A, false otherwise
evalTypeA, // Returns device Id
evalTypeB // Processes data in message and returns bytes read
);
on( "data", evalData );
Проблема здесь в том, что сообщения типа B не имеют идентификатора устройства, которому они принадлежат. Поэтому для правильной обработки сообщения мне нужен deviceId, который evalTypeA
вернул в предыдущем сообщении.
Моя идея решить эту проблему заключалась в том, чтобы передать идентификатор evalTypeB
:
const evalData = messages => {
let id = undefined;
id = ifElse(
isTypeA, // Returns true if type A, false otherwise
evalTypeA, // Returns device Id
evalTypeB( id ) // Processes data in message and returns bytes read
)( message );
}
Проблема в том, что это не сработает! evalTypeB
также возвращает число, и тогда я бы не знал, является ли то, что мне дано выражение ifElse
, числом прочитанных байтов или идентификатором!
Как бы вы решили эту проблему без мутаций и побочных эффектов?
По определению, чистая функция, которая вызывается многократно в качестве обратного вызова для on('data', callback)
, не может отслеживать состояние из предыдущих вызовов.
Имея это в виду, есть несколько вариантов, которые следует рассмотреть, чтобы попытаться минимизировать или локализовать побочные эффекты:
const processMsg = ifElse(isTypeA, evalTypeA, evalTypeB)
const handler = initialState => {
let state = initialState
return msg => {
state = processMsg(state, msg)
}
}
on('data', handler(42))
once
поддерживается эмиттером событий):const processMsg = ifElse(isTypeA, evalTypeA, evalTypeB)
const handler = state => msg =>
once('data', handler(processMsg(state, msg)))
once('data', handler(42))
Решение 2 настолько очевидно! Как я об этом не подумал? Спасибо !