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.
mobx源码解读4的更多相关文章
- mobx源码解读1
mobx是redux的代替品,其本身就是一个很好的MVVM框架.因此花点力气研究一下它. 网上下最新的2.75 function Todo() { this.id = Math.random() mo ...
- mobx源码解读3
计算属性 function Todo() { this.id = Math.random() mobx.extendObservable(this, { aaa: 222, bbb: 11, ccc: ...
- mobx源码解读2
我们将上节用到的几个类的构造器列举一下吧: function Reaction(name, onInvalidate) { if (name === void 0) { name = "Re ...
- SDWebImage源码解读之SDWebImageDownloaderOperation
第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...
- SDWebImage源码解读 之 NSData+ImageContentType
第一篇 前言 从今天开始,我将开启一段源码解读的旅途了.在这里先暂时不透露具体解读的源码到底是哪些?因为也可能随着解读的进行会更改计划.但能够肯定的是,这一系列之中肯定会有Swift版本的代码. 说说 ...
- SDWebImage源码解读 之 UIImage+GIF
第二篇 前言 本篇是和GIF相关的一个UIImage的分类.主要提供了三个方法: + (UIImage *)sd_animatedGIFNamed:(NSString *)name ----- 根据名 ...
- SDWebImage源码解读 之 SDWebImageCompat
第三篇 前言 本篇主要解读SDWebImage的配置文件.正如compat的定义,该配置文件主要是兼容Apple的其他设备.也许我们真实的开发平台只有一个,但考虑各个平台的兼容性,对于框架有着很重要的 ...
- SDWebImage源码解读_之SDWebImageDecoder
第四篇 前言 首先,我们要弄明白一个问题? 为什么要对UIImage进行解码呢?难道不能直接使用吗? 其实不解码也是可以使用的,假如说我们通过imageNamed:来加载image,系统默认会在主线程 ...
- SDWebImage源码解读之SDWebImageCache(上)
第五篇 前言 本篇主要讲解图片缓存类的知识,虽然只涉及了图片方面的缓存的设计,但思想同样适用于别的方面的设计.在架构上来说,缓存算是存储设计的一部分.我们把各种不同的存储内容按照功能进行切割后,图片缓 ...
随机推荐
- Linux--01入门
一.远程控制台 Linux和windows不太一样,win系列默认都有桌面,我们买了服务器,一般都用远程桌面去连接. 而linux一般都是为了追求低成本或者高性能,可能我们就不需要桌面了,所以使用命令 ...
- 虚幻4外包团队-推荐非常全面的的Unreal教程
<Unreal SDK 游戏开发从入门到精通(UnrealScript语法.UI Scene界面.UDK独立开发游戏)> 课程讲师:Shark 课程分类:.net 适合人群:初级 课时数 ...
- MyBatis入门学习教程-解决字段名与实体类属性名不相同的冲突
在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演示一下这种情况下的如何解决字段名与实体类属性名不相同的冲突. 一.准备演示需要使用的表和数据 CREATE TAB ...
- 报错:org.hibernate.AssertionFailure: null id in com.tt.hibernate.entities.News entry (don't flush the Session after an exception occurs)
在使用hibernate创建数据库的表格时,出现了如下报错: 十二月 28, 2016 10:17:02 上午 org.hibernate.tool.hbm2ddl.SchemaExport perf ...
- C语言中,定义的含义?声明的含义?它们之间的区别是什么?
在C语言中,对于定义和声明,也许我们非常的熟悉,但不一定真正的了解! 定义的含义:所谓定义,就是创建(编译器)一个对象,为这个对象分配一块内存空间并取名,也就是我们平常所说的变量名或对象名,一旦这个名 ...
- Eclipse调试时附加匹配版本的JAR包源码:Edit Source Loopup
- project euler 开坑
pe76: 要把100写成至少2个数的和的形式,有多少种方案数 整数拆分 f(i,j)表示把i拆分成不超过j的数的和的方案数 f(i,j) = f(i-j,j) + f(i,j-1) j <= ...
- eclipse @override注解出错
在工程中新建了一个接口,定义了一个methodA,然后写一个接口类实现该方法,并加上@override注解 项目提示@override出错,必须覆盖原方法XXX,解决办法 1)项目右键-project ...
- Summernote
Summernote是一个基于jquery的bootstrap超级简单WYSIWYG在线编辑器.Summernote非常的轻量级,大小只有30KB,支持Safari,Chrome,Firefox.Op ...
- Java 多张图片合成一张 drawImage
package com.yunfengtech.solution.business; import java.awt.Color; import java.awt.Graphics; import ...