这节介绍一下mobx的变更因子的稳定性。javascript
mobx整个系统是由ObservableValue, ComputedValue, Reaction这三个东西构建的java
ObservableValue 是最小的构成单位,ComputedValue是基于一个或多个ObservableValue构建的。Reaction则是由ObservableValue与ComputedValue驱动执行。性能优化
假若有ObservableValue a,b , ComputedValue c是由a, b组成,那么当a发生变化时,它会让c计算本身的新值。若是c与Reaction d有关联,那么d也会执行。这种关系机制,经过依赖收集实现。但在极端的场景中,a,b可能会被重复收集,形成没必要要的性能消耗。所以这些对象都有一个叫lowestObserverState的属性。性能
ObservableValue的父类就是BaseAtom, 它在这里继承于lowestObserverState,值为IDerivationState.NOT_TRACKING, 即-1。优化
ComputedValue没有继承BaseAtom或Atom,但结构与其余类差很少,lowestObserverState的值为IDerivationState.UP_TO_DATE,即为0
它还有一个dependenciesState, IDerivationState.NOT_TRACKING,即-1翻译
Reaction没有lowestObserverState, 只有dependenciesState ,值为 IDerivationState.NOT_TRACKING,即-1code
IDerivationState还有两个状态,POSSIBLY_STALE,即1, 和STALE 2.server
咱们能够将这四个状态翻译成对象
刚初始化
稳定
不知
不稳定
当咱们通知上层变动时,是经过propagateChanged方法,继承
function propagateChanged(observable) { //若是要通知上层发生变化,那么先断定本身是否稳定,不稳定就不要发出通知了 //只有稳定的东西,值是肯定的,可让上层的Computed或Action 不须要求值,直接用它的值 if (observable.lowestObserverState === IDerivationState.STALE) return; //将本身变成不稳定的,所以上层可能会在推导过程当中修改它 observable.lowestObserverState = IDerivationState.STALE; var observers = observable.observers; var i = observers.length; while (i--) { var d = observers[i]; //将它上层的依赖状态改为不稳定 if (d.dependenciesState === IDerivationState.UP_TO_DATE) d.onBecomeStale(); d.dependenciesState = IDerivationState.STALE; } }
计算属性要计算本身的值,先通过shouldCompute。这至关于性能优化,由于计算本身的值可能通过收集依赖等环节,能避开就避开。若是是计算属性,这时它肯定变成不稳定,须要进行计算。
function shouldCompute(derivation) { switch (derivation.dependenciesState) { case IDerivationState.UP_TO_DATE: return false; case IDerivationState.NOT_TRACKING: case IDerivationState.STALE: return true; case IDerivationState.POSSIBLY_STALE: //....略 } }
ComputedValue被ObservableValue变成不稳定它,它要能知本身的依赖发生变成,是经过propagateMaybeChanged
function propagateMaybeChanged(observable) { if (observable.lowestObserverState !== IDerivationState.UP_TO_DATE) return; observable.lowestObserverState = IDerivationState.POSSIBLY_STALE; var observers = observable.observers; var i = observers.length; while (i--) { var d = observers[i]; if (d.dependenciesState === IDerivationState.UP_TO_DATE) { d.dependenciesState = IDerivationState.POSSIBLY_STALE; d.onBecomeStale(); } } }
当ComputedValue计算出其值后,它又会将其依赖项的状态改为UP_TO_DATE.