【问题标题】:Do I have to ignore the concept of global module state with Immutable JS?我是否必须使用 Immutable JS 忽略全局模块状态的概念?
【发布时间】:2016-05-01 14:20:57
【问题描述】:

我刚刚偶然发现了 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()
})

在 socket 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 时,您可以在方法中更新组件状态,然后在组件的其他地方使用该新状态。

【问题讨论】:

    标签: javascript immutability immutable.js


    【解决方案1】:

    您的代码缺少一个简单的分配。当您使用不可变时,任何更新操作,如set,都会导致创建一个全新的对象。在您的情况下,以下代码 state.set("clients", clientsArray) 不会更改全局状态,但会返回一个带有修改后的 clients 列表的新实例。 要解决此问题,您只需使用调用结果更新全局状态,如下所示 -

    state = state.set("clients", clientsArray);

    或者你可以一次性重写这一切 -

    state = state.set("clients", state.get("clients").push(socket));

    希望这会有所帮助!

    根据经验,请记住,每当您调用更改/改变不可变对象的方法时,您总是需要进行赋值。

    【讨论】:

    • 这正是我所需要的,谢谢。我知道返回了一个新副本,我只是不确定是否可以重置全局。
    猜你喜欢
    • 1970-01-01
    • 2018-12-03
    • 1970-01-01
    • 2016-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多