這節介紹一下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.