Open gismanli opened 7 years ago
Observable 是 MobX 的重要构成部分,其包含:
observable array
observable object
observable map
也许我们之前会有这样的疑问:为什么我们更改数据时就会触发响应更新呢?
让我们来看一下是具体是如何实现的。
顾名思义,atom的意思就是原子,在 mobx 中任何可以存储状态的都是一个 Atom。
Atom 有两个重要的职责:
reportObserved
来分析下源代码:
先看下 interface IObservable
interface IObservable
export interface IDepTreeNode { name: string; observing?: IObservable[]; } export enum IDerivationState { NOT_TRACKING = -1, UP_TO_DATE = 0, POSSIBLY_STALE = 1, STALE = 2 } export interface IDerivation extends IDepTreeNode { observing: IObservable[]; newObserving: IObservable[]; dependenciesState: IDerivationState; runId: number; unboundDepsCount: number; __mapid: string; onBecomeStale(); recoverFromError(); // TODO: revisit implementation of error handling } export interface IObservable extends IDepTreeNode { diffValue: number; lastAccessedBy: number; lowestObserverState: IDerivationState; isPendingUnobservation: boolean; observers: IDerivation[]; observersIndexes: {}; onBecomeUnobserved(); }
这里预定义了一堆属性,继续看 Atom 定义:
export interface IAtom extends IObservable { } export class BaseAtom implements IAtom { isPendingUnobservation = true; // for effective unobserving. BaseAtom has true, for extra optimization, so it's onBecomeUnobserved never get's called, because it's not needed observers = []; observersIndexes = {}; diffValue = 0; lastAccessedBy = 0; lowestObserverState = IDerivationState.NOT_TRACKING; constructor(public name = "Atom@" + getNextId()) { } public onBecomeUnobserved() { // noop } public reportObserved() { reportObserved(this); } public reportChanged() { transactionStart("propagatingAtomChange", null, false); propagateChanged(this); transactionEnd(false); } toString() { return this.name; } }
这里主要是定义了 reportObserved 和 reportChanged 方法:
reportChanged
首先看下类 ObservableValue 的定义:
ObservableValue
export type IUNCHANGED = {}; export const UNCHANGED: IUNCHANGED = {}; export interface IObservableValue<T> { get(): T; set(value: T): void; intercept(handler: IInterceptor<IValueWillChange<T>>): Lambda; observe(listener: (newValue: T, oldValue: T) => void, fireImmediately?: boolean): Lambda; } export class ObservableValue<T> extends BaseAtom implements IObservableValue<T> { hasUnreportedChange = false; protected value: T = undefined; constructor(value: T, protected mode: ValueMode, name = "ObservableValue@" + getNextId()) { super(name); const [childmode, unwrappedValue] = getValueModeFromValue(value, ValueMode.Recursive); // If the value mode is recursive, modifiers like 'structure', 'reference', or 'flat' could apply if (this.mode === ValueMode.Recursive) this.mode = childmode; this.value = makeChildObservable(unwrappedValue, this.mode, this.name); } public set(newValue: T) { const oldValue = this.value; newValue = this.prepareNewValue(newValue) as any; if (newValue !== UNCHANGED) { this.setNewValue(newValue); } } prepareNewValue(newValue): T | IUNCHANGED { checkIfStateModificationsAreAllowed(); const changed = valueDidChange(this.mode === ValueMode.Structure, this.value, newValue); if (changed) return makeChildObservable(newValue, this.mode, this.name); return UNCHANGED; } setNewValue(newValue: T) { const oldValue = this.value; this.value = newValue; this.reportChanged(); } public get(): T { this.reportObserved(); return this.value; } public observe(listener: (newValue: T, oldValue: T) => void, fireImmediately?: boolean): Lambda { if (fireImmediately) listener(this.value, undefined); return registerListener(this, listener); } toJSON() { return this.get(); } toString() { return `${this.name}[${this.value}]`; } }
前言
Observable 是 MobX 的重要构成部分,其包含:
observable array
observable object
observable map
也许我们之前会有这样的疑问:为什么我们更改数据时就会触发响应更新呢?
让我们来看一下是具体是如何实现的。
Atom
顾名思义,atom的意思就是原子,在 mobx 中任何可以存储状态的都是一个 Atom。
Atom 有两个重要的职责:
reportObserved
),这就建立起了 状态使用 和 运行函数 之间的桥梁。来分析下源代码:
这里预定义了一堆属性,继续看 Atom 定义:
这里主要是定义了
reportObserved
和reportChanged
方法:reportObserved
: 通过调用这个方法来通知 mobx 该 atom 被使用了。reportChanged
:在 mobx 更改信号已通知其所有观察者们失效后调用该方法。ObservableValue
首先看下类
ObservableValue
的定义: