ifElse语句状态?

问题描述 投票:1回答:1

背景

我正在制作一个从多个设备接收消息的应用程序。收到消息后,将使用给定消息触发事件:

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

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

javascript sockets functional-programming ramda.js
1个回答
5
投票

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

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

  1. 关闭状态,保持逻辑没有副作用:
const processMsg = ifElse(isTypeA, evalTypeA, evalTypeB)

const handler = initialState => {
  let state = initialState
  return msg => {
      state = processMsg(state, msg)
  }
}

on('data', handler(42))
  1. 递归附加一个新的处理程序,在每次调用结束时只为每个消息调用一次,将效果限制为处理程序注册(假设事件发射器支持once):
const processMsg = ifElse(isTypeA, evalTypeA, evalTypeB)

const handler = state => msg =>
  once('data', handler(processMsg(state, msg)))

once('data', handler(42))
© www.soinside.com 2019 - 2024. All rights reserved.