带状态的 ifElse 语句?
ifElse statement with state?
背景
我正在制作一个从多个设备接收消息的应用程序。收到消息后,将使用给定消息触发事件:
on( "data", message => {
//doSomething
} );
挑战
此函数接收两种类型的消息:A 和 B:
- 消息A有设备的id
- 消息 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 的消息没有它们所属设备的 ID。因此,为了正确处理消息,我需要 evalTypeA
在上一条消息中返回的 deviceId。
我解决这个问题的想法是将 Id 传递给 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
也是 returns 一个数字,然后我不知道 ifElse
表达式给我的是读取的字节数还是 Id!
问题
在没有突变和副作用的情况下,你如何解决这个问题?
根据定义,作为 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))
背景
我正在制作一个从多个设备接收消息的应用程序。收到消息后,将使用给定消息触发事件:
on( "data", message => {
//doSomething
} );
挑战
此函数接收两种类型的消息:A 和 B:
- 消息A有设备的id
- 消息 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 的消息没有它们所属设备的 ID。因此,为了正确处理消息,我需要 evalTypeA
在上一条消息中返回的 deviceId。
我解决这个问题的想法是将 Id 传递给 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
也是 returns 一个数字,然后我不知道 ifElse
表达式给我的是读取的字节数还是 Id!
问题
在没有突变和副作用的情况下,你如何解决这个问题?
根据定义,作为 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))