ifElse语句状态?

时间:2018-05-02 08:06:02

标签: javascript sockets functional-programming ramda.js

背景

我正在创建一个接收来自多个设备的消息的应用。收到消息后,将使用给定消息触发事件:

on( "data", message => {
    //doSomething
} );

挑战

此函数接收两种类型的消息:A和B:

  • 消息A具有设备的ID
  • 消息B有一些关于deivce的信息

我处理这个问题的第一个方法如下:

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也返回一个数字,然后我不知道ifElse表达式给出的是读取的字节数是多少还是Id!

问题

如果没有突变和副作用,你会如何解决这个问题?

1 个答案:

答案 0 :(得分:5)

根据定义,作为on('data', callback)的回调被称为重复次数的纯函数无法跟踪先前调用的状态。

考虑到这一点,有几种方法可以考虑帮助尝试最小化或本地化副作用:

  1. 关闭状态,保持逻辑没有副作用:
  2. const processMsg = ifElse(isTypeA, evalTypeA, evalTypeB)
    
    const handler = initialState => {
      let state = initialState
      return msg => {
          state = processMsg(state, msg)
      }
    }
    
    on('data', handler(42))
    
    1. 递归附加一个新的处理程序,在每次调用结束时只对每个消息调用一次,将效果限制为处理程序注册(假设事件发射器支持once):< / LI>
      const processMsg = ifElse(isTypeA, evalTypeA, evalTypeB)
      
      const handler = state => msg =>
        once('data', handler(processMsg(state, msg)))
      
      once('data', handler(42))