zoukankan      html  css  js  c++  java
  • mobx源码解读4

    这节介绍一下mobx的变动因子的稳定性。

    mobx整个系统是由ObservableValue, ComputedValue, Reaction这三个东西构建的

    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,即-1

    IDerivationState还有两个状态,POSSIBLY_STALE,即1, 和STALE 2.

    我们可以将这四个状态翻译成

    • IDerivationState.NOT_TRACKING: 不追踪,或者刚初始化
    • IDerivationState.UP_TO_DATE: 已经更新,或者稳定
    • IDerivationState.POSSIBLY_STALE: 可能不稳定,或者不知
    • IDerivationState.STALE: 不稳定

    当我们通知上层变更时,是通过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.

  • 相关阅读:
    关于网络字节序(network byte order)和主机字节序(host byte order)
    关于垃圾回收,我来解释下为什么LocalConnection可以实现垃圾回收
    解决Form中ExternalInterface的Bug问题
    AS3里var aa:String是null还是""?
    IE并发连接限制(as)
    tar
    mysql默认端口号3306
    flex经验
    这个游戏不错
    nginx介绍
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/6059216.html
Copyright © 2011-2022 走看看