如何使用功能方法更新内部范围的值?

时间:2017-08-29 20:03:42

标签: javascript node.js functional-programming ramda.js

我有一个案例,我从客户端获取两个字符串的数组,并在服务器端映射它们为每个字符串打开一个流。 (在代码示例中,我使用setInterval而不是实际数据流来保持尽可能简单。)

我还在一个对象中重构了这个数据,所以我可以保留我稍后会更新的值。每当触发setInterval时,我都会增加与我正在映射的迭代对应的键的值。

const stream = (arr) => {

    // arr = ['firstValue', 'secondValue']

    // the object to store the values which will be sent to the client
    const restructure = {
        [arr[0]]: 0,
        [arr[1]]: 0
    }

    arr.map((i) => {
        // setInterval as a placeholder stream
        setInterval(() => {
            restructure[i]++
            // instead of logging, the updated object is sent to client
            console.log(restructure)
        }, 2000)
    })
}

在提升值之后,我将更新后的对象发送回客户端。显然这是有效的,但我想用更实用的方法进行更新操作。

我尝试过Ramda和Lodash / Fp的一些方法,但似乎无法从不同的范围更新对象。

通常最终会发生的事情是价值受到冲击,然后在下一个时间间隔内回到原来的价值。

是否有可行的方法通过某种功能setState从内部范围更新此数据?

1 个答案:

答案 0 :(得分:3)

Ramda的设计原则是永不修改用户数据。这并不意味着你不能使用Ramda这样做,但Ramda功能本身并不能帮助你做到这一点。这是非常有意的;不可变数据结构是函数式编程的重要概念之一。

至于你的例子,我注意到的第一件事是你的stream函数没有返回任何内容。同样,这在FP中是个奇怪的事情。

现在,关于在函数中使用Ramda,您可以使用let restructure = fromPairs(map(key => [key, 0], arr))开始。

setInterval内,你可以自己重置restructurerestructure = evolve({[i]: R.inc}, restructure)

总而言之,我们可以通过

获得与您的示例相似的内容
const stream = (arr) => {
  let restructure = fromPairs(map(key => [key, 0], arr));
  R.map((key) => {
    setInterval(() => {
      restructure = evolve({[key]: R.inc}, restructure            
      console.log(restructure);
    }, 2000)
  }, arr)

  return () => restructure
}

同样,Ramda实际上并没有更新该变量。但它肯定不会阻止你重新分配它。

您可以在 Ramda REPL 中看到略有不同的变化。