Mobx 如何缓存计算值?

kev*_*ler 2 javascript mobx

我正在使用 Mobx 构建一个 webgl 游戏引擎。我没有将它与反应一起使用。我正在使用它来增强实体组件系统。我有实体类

import {observable, observe, computed, autorun} from 'mobx';

class Entity {
  @observable position = [0,0,0]
  @observable rotation = [0,0,0]

  @computed get modelMat(){
    return position * rotation;
  }
}
Run Code Online (Sandbox Code Playgroud)

我使用这个实体,如:

var ent = new Entity();
entity.position = [0,10,0];
if(entity.modelMat == 6){
  // do something
}
Run Code Online (Sandbox Code Playgroud)

我的理解是,modelMat像这样直接阅读不是最佳做法。它导致计算被重新计算。它没有被缓存。这对我的游戏引擎是有害的,因为我可能会以 60fps 的高速访问这些计算值。

这对我来说似乎不直观,因为您使用gethelper定义了计算,然后不应该将它用作 getter?调试computedRequiresReaction设置可用于防止这种直接计算读取的模式。

configure({
  computedRequiresReaction: true
});
Run Code Online (Sandbox Code Playgroud)

我的问题是如何缓存或记忆这些将频繁访问的计算值?为了避免这种情况,我开始使用一种使用自动运行的模式,在计算更改时更新局部变量。看起来像:

class Entity {
  @observable position = [0,0,0]
  @observable rotation = [0,0,0]

  modelMat = []

  constructor(){
    autorun(() => {
      this.modelMat = this.computedModelMat()
    })
  }

  @computed get computedModelMat(){
    return position * rotation;
  }
}
Run Code Online (Sandbox Code Playgroud)

这为类启用了一个接口,以便ent.modelMat仍然可以快速访问,但不会每次都重新计算。有没有更好的建议模式?对每个计算进行自动运行似乎是多余的。我的一些类最终有许多自动运行处理程序来缓存这些值。

mwe*_*ate 5

请注意,计算支持一个keepAlive选项,即使没有观察者,它也会强制 mobx 缓存值。而且它实际上比使用 autorun 来观察更有效,因为有一些内部优化应用于这个标志。

但是有一点内存泄漏的风险:如果计算引用的任何内容仍然存在,则计算将不会被清除。但是,如果您仅指类本地事物,则应该保存。