如何使用功能方法从内部范围更新值?
How to update values from an inner scope with a functional approach?
我有一个案例,我从客户端获取两个字符串的数组,然后在服务器端映射它们,为它们中的每一个打开一个流。 (在代码示例中,我使用 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
从内部范围更新此数据?
Ramda 的设计原则是永不修改用户数据。这并不意味着您不能使用 Ramda 这样做,但 Ramda 函数本身不会帮助您这样做。这是故意的;不可变数据结构是函数式编程的重要概念之一。
关于您的示例,我注意到的第一件事是您的 stream
函数没有 return 任何东西。同样,这在 FP 中是一件奇怪的事情。
现在,关于在您的函数中使用 Ramda,您可以先使用 let restructure = fromPairs(map(key => [key, 0], arr))
。
在您的 setInterval
中,您可以自己重置 restructure
值,例如 restructure = 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.
中看到它的细微变化
我有一个案例,我从客户端获取两个字符串的数组,然后在服务器端映射它们,为它们中的每一个打开一个流。 (在代码示例中,我使用 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
从内部范围更新此数据?
Ramda 的设计原则是永不修改用户数据。这并不意味着您不能使用 Ramda 这样做,但 Ramda 函数本身不会帮助您这样做。这是故意的;不可变数据结构是函数式编程的重要概念之一。
关于您的示例,我注意到的第一件事是您的 stream
函数没有 return 任何东西。同样,这在 FP 中是一件奇怪的事情。
现在,关于在您的函数中使用 Ramda,您可以先使用 let restructure = fromPairs(map(key => [key, 0], arr))
。
在您的 setInterval
中,您可以自己重置 restructure
值,例如 restructure = 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.
中看到它的细微变化