我刚刚偶然发现了 Immutable JS,我相信它看起来是一个非常有趣的库,可以减少由于程序员错误/意外突变而出现错误的可能性,以及它提供的性能优化,但是我很难理解我是如何做到这一点的。可以跟踪模块内的状态。
例如,如果我运行一个支持多个流的 socket.io 服务器,我通常会在该模块的全局上下文中使用两个变量来跟踪已连接的客户端和当前可用的流:
var clients = []
var streams = []
如果用户要连接,我可以简单地在套接字 ios io.on("connection")
事件监听器中使用 .push
,我可以放心,我的客户端状态现在将包含新加入的套接字。
在 Immutable JS 中,我有一个模块全局的对象,现在看起来像:
var state = Immutable.Map({
clients : Immutable.List.of(),
streams : Immutable.List.of()
})
在套接字 io 的连接处理程序内部,如何更新全局状态?我相信 Immutable JS 是这样工作的,所以维护应用程序状态似乎根本不可能(因为我目前的思考方式)
// Define the Immutable array, this remains constant throughout the application
var state = Immutable.Map({
clients : Immutable.List.of(),
streams : Immutable.List.of()
})
io.on("connection", (socket) => {
console.log(state.clients)
// I would like to update the state of clients here, but I believe that
// I am only able to make a local copy within the context of the current
// scope, I would then lose access to this on the next socket joining?
var clientsArray = state.clients
clientsArray.push(socket)
state.set("clients", clientsArray)
console.log(state.clients)
})
根据我的理解,我相信两个客户端连接上的 console.log 语句将产生以下输出:
// First client connects
[]
[ { socket object } ]
// Second client connects
[]
[ { socket object } ]
我是否可以更新该对象,以便我能够得到
[ { socket object }, { socket object } ]
或者我是否需要坚持使用全局可变状态?我问这个问题的唯一原因是因为当我过去使用过 React 时,您可以在方法中更新组件状态,然后在组件中的其他地方使用该新状态。
最佳答案
您的代码缺少一个简单的分配。当您使用不可变时,任何更新操作(例如 set
)都会导致创建一个全新的对象。在您的情况下,以下代码 state.set("clients", clientArray)
不会更改全局状态,但会返回一个具有修改后的 clients
列表的新实例。
要解决此问题,您只需使用调用结果更新全局状态,如下所示 -
state = state.set("clients",clientsArray);
或者你可以一次性重写这一切 -
state = state.set("clients", state.get("clients").push(socket));
希望这有帮助!
根据经验,请记住,每当您调用更改/改变不可变对象(immutable对象)的方法时,您始终需要进行赋值。
关于javascript - 我是否必须忽略 Immutable JS 的全局模块状态的概念?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36967667/