这节介绍一下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.

mobx源码解读4的更多相关文章

  1. mobx源码解读1

    mobx是redux的代替品,其本身就是一个很好的MVVM框架.因此花点力气研究一下它. 网上下最新的2.75 function Todo() { this.id = Math.random() mo ...

  2. mobx源码解读3

    计算属性 function Todo() { this.id = Math.random() mobx.extendObservable(this, { aaa: 222, bbb: 11, ccc: ...

  3. mobx源码解读2

    我们将上节用到的几个类的构造器列举一下吧: function Reaction(name, onInvalidate) { if (name === void 0) { name = "Re ...

  4. SDWebImage源码解读之SDWebImageDownloaderOperation

    第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...

  5. SDWebImage源码解读 之 NSData+ImageContentType

    第一篇 前言 从今天开始,我将开启一段源码解读的旅途了.在这里先暂时不透露具体解读的源码到底是哪些?因为也可能随着解读的进行会更改计划.但能够肯定的是,这一系列之中肯定会有Swift版本的代码. 说说 ...

  6. SDWebImage源码解读 之 UIImage+GIF

    第二篇 前言 本篇是和GIF相关的一个UIImage的分类.主要提供了三个方法: + (UIImage *)sd_animatedGIFNamed:(NSString *)name ----- 根据名 ...

  7. SDWebImage源码解读 之 SDWebImageCompat

    第三篇 前言 本篇主要解读SDWebImage的配置文件.正如compat的定义,该配置文件主要是兼容Apple的其他设备.也许我们真实的开发平台只有一个,但考虑各个平台的兼容性,对于框架有着很重要的 ...

  8. SDWebImage源码解读_之SDWebImageDecoder

    第四篇 前言 首先,我们要弄明白一个问题? 为什么要对UIImage进行解码呢?难道不能直接使用吗? 其实不解码也是可以使用的,假如说我们通过imageNamed:来加载image,系统默认会在主线程 ...

  9. SDWebImage源码解读之SDWebImageCache(上)

    第五篇 前言 本篇主要讲解图片缓存类的知识,虽然只涉及了图片方面的缓存的设计,但思想同样适用于别的方面的设计.在架构上来说,缓存算是存储设计的一部分.我们把各种不同的存储内容按照功能进行切割后,图片缓 ...

随机推荐

  1. xcode中使用xib添加autolayout中constrain to margins的不同

    在使用xcode7 在storyboard中添加autolayout中发现 如果添加在view 直接添加到viewcontroller的view 上 constrain to margins    只 ...

  2. 开源共享一个训练好的中文词向量(语料是维基百科的内容,大概1G多一点)

    使用gensim的word2vec训练了一个词向量. 语料是1G多的维基百科,感觉词向量的质量还不错,共享出来,希望对大家有用. 下载地址是: http://pan.baidu.com/s/1boPm ...

  3. 感知器、逻辑回归和SVM的求解

    这篇文章将介绍感知器.逻辑回归的求解和SVM的部分求解,包含部分的证明.本文章涉及的一些基础知识,已经在<梯度下降.牛顿法和拉格朗日对偶性>中指出,而这里要解决的问题,来自<从感知器 ...

  4. Django 之 models的 F() 和 Q() 函数

    前提: app名称为core,models.py 如下: #coding: utf8 import datetime from django.db import models class Order( ...

  5. OC中copy的使用

    @property内存管理策略的选择 1.非ARC 1> copy : 只用于NSString\block: 2> retain : 除NSString\block以外的OC对象: 3&g ...

  6. 转ASP.NET1.1请求队列限制

    在教务web的选课的维护中,经常面临asp.net1.1报错,在客户端跳转到用户自定义页面,在服务器端可以看到如下错误信息: “/”应用程序中的服务器错误. 服务器太忙 说明: 执行当前 Web 请求 ...

  7. AUTOIT解决域控普通用户以管理员身份安装软件方法

    windows域管理,本是很好的管理方式,方便的软件分发,权限控制等功能.不过由于我处软件分发总有那么一些电脑没有成功安装,或是新装的电脑安装软件时漏了安装一些软件,而这些软件需要管理员权限安装的,用 ...

  8. Linux下的shell编程(三)BY 四喜三顺

    正则表达式:-------------------------------------------------------------------------------------------^   ...

  9. Python-7 列表list

    #1 创建列表.向列表中添加元素 1) 列表名称.append(*) 2) 列表名称.extend([*,*,...]) 3) 列表名称.insert(位置,*) member = ['小甲鱼','小 ...

  10. cctype头文件中的一些内容

    1. string 标准库 1.1初始化 string s1; 默认构造函数s1为空 string s2(s1); 将s2初始化为s1的一个副本 string s3(“value”); 将s3初始化为 ...