我正在使用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;
}
}
我像这样使用这个实体:
var ent = new Entity();
entity.position = [0,10,0];
if(entity.modelMat == 6){
// do something
}
我的理解是,像这样直接阅读modelMat
并不是最佳实践。它导致重新计算计算。它没有被缓存。这对我的游戏引擎不利,因为我可能会以60fps的高速度访问这些计算值。
这在我看来是不直观的,因为您使用get
辅助函数定义了计算对象,然后又不应该将其用作吸气剂?调试computedRequiresReaction
设置可用于防止这种直接计算读数的模式。
configure({
computedRequiresReaction: true
});
然后我的问题是如何缓存或记住这些将经常访问的计算值?为避免这种情况,我开始使用一种使用自动运行的模式,以在计算出的更改时更新局部变量。它看起来像:
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;
}
}
这将启用该类的接口,以便ent.modelMat
仍可快速访问,但不会每次都重新计算。有更好的建议模式吗?为每个计算出的文件自动运行似乎很多余。我的某些类最终有许多自动运行处理程序来缓存这些值。
是,您实际上正在使用推荐的方法:https://github.com/mobxjs/mobx/issues/356
只要
computed
不使用reaction
值,就不会记住它,因此它就像普通的渴望评估功能一样。如果您将在autorun
中使用[getter],则此行为将更改,并且您不会看到不必要的计算。...
但是请注意memory leaks。问题中的代码不会泄漏,但是我不确定您的所有代码:
computed未使用 reaction
值,就可以将其忽略。 MobX不会重新计算所有内容,并且该计算不会使任何其他计算保持活动状态。
const VAT = observable(1.2)
class OrderLine {
@observable price = 10
@observable amount = 1
constructor() {
// this autorun will be GC-ed together with the current orderline instance
this.handler = autorun(() => {
doSomethingWith(this.price * this.amount)
})
// this autorun won't be GC-ed together with the current orderline instance
// since VAT keeps a reference to notify this autorun,
// which in turn keeps 'this' in scope
this.handler = autorun(() => {
doSomethingWith(this.price * this.amount * VAT.get())
})
// So, to avoid subtle memory issues, always call..
this.handler()
// When the reaction is no longer needed!
}
}
mobx world
,而mobx担心[外面]发生了什么。在mobx
系统中,什么都不是[[observing