首页 > 解决方案 > setTimeout 函数 Object.assign 分配一个变量 - 但对变量的突变会带回原始变量

问题描述

抱歉标题混淆了,不知道如何简洁地描述这一点。

我有一个通过 NodeJS 运行的类。简化后,它看起来像这样:

constructor(){
  // ...
  this.state = {
    gambits: []
  }

  this.render = this.render.bind(this)

  //...
  this.render()

}

我有 websocket 侦听器,它们触发函数以从数据库设置更新的数据并将它们放入 this.state 变量中。

这个想法是渲染函数应该通过 setTimeout 每隔几秒运行一次,当它运行时,它会从 this.state 中获取数据,创建一个新对象供我使用。每次渲染运行时,它都应该抓取 this.state.gambits,循环并从其他处于状态的对象中复制数据。渲染函数看起来像这样:

render(){

  let gambits = Object.assign([], this.state.gambits)
  .sort(() => { /* ... */ })
  .map(g => {
    // g looks like this
    // {
    //   id: 1,
    //   priority: 2,
    //   enabled: true,
    //   conditions: [ 2 ],
    //   reactions: [ 1, 2 ]
    // }

    // For each gambit that's enabled and configured...
    if (g.enabled && g.conditions.length && g.reactions.length) {
      // grab the conditions...

      console.log('conditions: ', g.conditions)
      g.conditions = g.conditions.map((c) => {
        return this.state.conditions.find((con) => {
          return con.id = c
        })
      })

      return g
    } else {
      return null
    }

  })

  clearTimeout(this.timeout)
  this.timeout = setTimeout(this.render, 5000)

}

您可以看到我如何使用 .map() 循环遍历 gambits 数组,g.condition 数组包含与条件对象 ID 号匹配的 ID 号。

我使用 .find() 找到具有匹配 id 的条件对象,并返回匹配的条件对象。

第一次通过渲染功能,一切似乎都按预期工作。

渲染的后续执行给了我奇怪的结果。

第一次通过,我看到了我的期望:

[
  {
    id: 1,
    group: 1,
    priority: 99999,
    enabled: true,
    conditions: [
      {
        id: 5,
        group: '1',
        expressions: [
          {
            data: { deviceId: '13', dataPointIndex: '0' },
            operator: '>=',
            value: '75',
            plateValue: '0'
          }
        ]
      }
    ],
    reactions: [
      {
        id: 5,
        group: '1',
        expression: { deviceId: '13', outputIndex: '0', value: 'true' }
      }
    ]
  }
]

而且,第二次通过:

[
  {
    id: 1,
    group: 1,
    priority: 99999,
    enabled: true,
    conditions: [
      <ref *1> {          // <<<<---------- ????? <ref *1> ?
        id: [Circular *1],
        group: '1',
        expressions: [
          {
            data: { deviceId: '13', dataPointIndex: '0' },
            operator: '>=',
            value: '75',
            plateValue: '0'
          }
        ]
      }
    ],
    reactions: [
      <ref *2> {
        id: [Circular *2],
        group: '1',
        expression: { deviceId: '13', outputIndex: '0', value: 'true' }
      }
    ]
  }
]

因此,我console.log('conditions: ', g.conditions)在对 g.conditions 进行任何突变之前在 .map() 中间添加了一个。

第一次通过,我看到了我的期望:

conditions: [ 5 ]

第二次通过我看到

conditions:  [
  <ref *1> {
    id: [Circular *1],
    group: '1',
    expressions: [ [Object] ]
  }
]

好的,所以一定是 this.state.gambits 正在更新,或者我引用的是同一个对象?

我用于不引用数组Object.assign([], this.state.gambits)的明确目的。this.state.gambits但它似乎仍在变异它。非常混乱。

任何想法为什么会发生这种情况或我需要做些什么来解决这个问题?我超级困惑。

谢谢

标签: node.js

解决方案


推荐阅读