Mobx 源码解析(二):深入解析 ComputedValue
2023-11-04 14:08:36
前言
在上一章中,我们对 Mobx 的基本概念和整体架构进行了介绍。我们了解到,Mobx 的核心思想是通过观察者模式来实现响应式更新。在这一章中,我们将深入分析 Mobx 中 ComputedValue
类的源码实现,了解其内部运作机制以及如何实现响应式更新。我们将从 ComputedValue
类的定义开始,然后逐步探究其关键方法和属性,揭示其作为 Mobx 响应式系统基石的作用。
ComputedValue 类的定义
ComputedValue
类是 Mobx 中一个重要的类,它是响应式计算的基础。该类实现了 IObservable
, IComputedValue
, IDerivation
三个接口,其中 IObservable
接口定义了可观察对象的公共方法和属性,IComputedValue
接口定义了计算值特有的方法和属性,IDerivation
接口定义了派生对象(如计算值和反应式跟踪器)的公共方法和属性。
export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDerivation {
...
}
ComputedValue 类的关键方法和属性
构造函数
ComputedValue
类的构造函数接收一个计算函数作为参数,该函数用于计算 ComputedValue
的值。在构造函数中,会创建一个新的派生对象(即 ComputedValue
实例),并将其添加到 Mobx 的派生对象列表中。同时,还会创建一个反应式跟踪器,用于跟踪 ComputedValue
所依赖的可观察对象的变化。
constructor(options: IComputedValueOptions<T>) {
...
this._derivation = new ComputedValueDerivation(this, options.get, options.set, options.name);
...
}
get 方法
get
方法是 ComputedValue
类的一个重要方法,它用于获取 ComputedValue
的值。当调用 get
方法时,会首先检查 ComputedValue
是否已经计算过其值。如果已经计算过,则直接返回计算结果。如果尚未计算,则会调用计算函数计算 ComputedValue
的值,并将计算结果缓存起来。
get(): T {
...
if (this.isComputing !== true) {
this.trackAndCompute();
}
if (globalState.strict && !this.isComputing && (this.dependenciesState === 1 || this.dependenciesState === 3)) {
console.warn(`[MobX] Computed value ` + this.name + ` is being read outside a reactive context`);
}
...
}
set 方法
set
方法是 ComputedValue
类的一个可选方法,它用于设置 ComputedValue
的值。当调用 set
方法时,会首先检查 ComputedValue
是否允许被设置。如果允许,则会调用计算函数计算 ComputedValue
的新值,并将新值缓存起来。同时,还会通知所有依赖于该 ComputedValue
的可观察对象更新其值。
set(value: T): void {
...
if (this.setter !== undefined) {
this.setter.call(this.context, value);
} else if (globalState.strict) {
console.warn(`[MobX] Computed value ` + this.name + ` is trying to update itself. ` + `It will be readonly after the next turn.`);
}
...
}
autorun 方法
autorun
方法是 ComputedValue
类的一个静态方法,它用于创建一个反应式跟踪器。反应式跟踪器会跟踪 ComputedValue
所依赖的可观察对象的变化,并在这些可观察对象变化时自动重新计算 ComputedValue
的值。
static autorun(f: IAutorunOptions | IFn0<IDisposer>): IDisposable {
const reaction = new Reaction(undefined, f, undefined, false);
reaction.runReaction();
return reaction.getDisposer();
}
ComputedValue 类作为 Mobx 响应式系统基石的作用
ComputedValue
类是 Mobx 响应式系统的一个基石。它允许开发者定义计算值,这些计算值可以依赖于其他可观察对象。当这些可观察对象发生变化时,ComputedValue
会自动重新计算其值,并通知所有依赖于它的可观察对象更新其值。这种响应式更新机制使得 Mobx 能够轻松地构建出复杂的、响应式的应用程序。
总结
在这一章中,我们深入分析了 ComputedValue
类的源码实现,了解了其内部运作机制以及如何实现响应式更新。我们从 ComputedValue
类的定义开始,然后逐步探究其关键方法和属性,揭示其作为 Mobx 响应式系统基石的作用。通过对 ComputedValue
类的深入理解,我们对 Mobx 的响应式编程模型有了更深入的认识。