Mobx6核心源码解析(三): ObservableObjectAdministration

779 阅读2分钟

image.png 上一篇探究了observable方法内部的执行机制,讲到adm.extend_( key, descriptor[key as any],true)将target与obj对象关联了起来。本文将从这里继续,解析adm的classObservableObjectAdministration

let target = observable(obj)

ObservableObjectAdministration

ObservableObjectAdministration作用是管理target的属性的读取。它在Mobx的世界里处于leader地位,这一点从它的Administration的命名也可以看出来。

  • _extend ObservableObjectAdministration实例的_extend,经过了相当fuck的过程后,调用了实例的defineObservableProperty_方法:
  • defineObservableProperty_
 defineObservableProperty_(
        key: PropertyKey,
        value: any,
        enhancer: IEnhancer<any>,
        proxyTrap: boolean = false
    ): boolean | null {
        try {
            startBatch()

            // Delete
            const deleteOutcome = this.delete_(key)
            if (!deleteOutcome) {
                // Failure or intercepted
                return deleteOutcome
            }

            // ADD interceptor
            if (hasInterceptors(this)) {
                const change = interceptChange<IObjectWillChange>(this, {
                    object: this.proxy_ || this.target_,
                    name: key,
                    type: ADD,
                    newValue: value
                })
                if (!change) return null
                value = (change as any).newValue
            }

            const cachedDescriptor = getCachedObservablePropDescriptor(key)
            const descriptor = {
                configurable: globalState.safeDescriptors ? this.isPlainObject_ : true,
                enumerable: true,
                get: cachedDescriptor.get,
                set: cachedDescriptor.set
            }

            // Define
            if (proxyTrap) {
                if (!Reflect.defineProperty(this.target_, key, descriptor)) {
                    return false
                }
            } else {
                defineProperty(this.target_, key, descriptor)
            }

            const observable = new ObservableValue(
                value,
                enhancer,
                __DEV__ ? `${this.name_}.${key.toString()}` : "ObservableObject.key",
                false
            )

            this.values_.set(key, observable)

            // Notify (value possibly changed by ObservableValue)
            this.notifyPropertyAddition_(key, observable.value_)
        } finally {
            endBatch()
        }
        return true
    }

这里终于看到了defineProperty(this.target_, key, descriptor)的字眼,意味着target对象的key的descriptor在这里被设置完成了。但是这个descriptor是来自于getCachedObservablePropDescriptor的,并且和obj对象的descriptor一点关系都没有,getter和setter也都来自于实例

{
    get() {
        return this[$mobx].getObservablePropValue_(key)
    },
    set(value) {
        return this[$mobx].setObservablePropValue_(key, value)
    }
}

在介绍getObservablePropValue_setObservablePropValue_之前,需要先介绍另一个嘉宾values_

  • values_ values_是一个Map,key对应的是obj的属性,value是ObservableValue实例,这个实例保存了obj对应key的descriptor.
  public values_ = new Map<PropertyKey, ObservableValue<any> | ComputedValue<any>>(),
  defineObservableProperty_(){
      ...
      const observable = new ObservableValue(value,enhancer, "ObservableObject.key",false)
      this.values_.set(key, observable)
      ...
  }
  • getObservablePropValue_ 这是target真正的getter,它是从ObservableValue实例中获取值。
 getObservablePropValue_(key: PropertyKey): any {
    return this.values_.get(key)!.get()
}
  • setObservablePropValue_ 这是target真正的setter,简化后可以看到这个这里还是通过ObservableValue实例进行新值的设置
setObservablePropValue_(key: PropertyKey, newValue): boolean | null {
    const observable = this.values_.get(key)
    if (observable instanceof ComputedValue) {
        observable.set(newValue)
        return true
    }
    ...
    newValue = (observable as any).prepareNewValue_(newValue)

    // notify spy & observers
    if (newValue !== globalState.UNCHANGED) {
        const notify = hasListeners(this)
        ;(observable as ObservableValue<any>).setNewValue_(newValue)
        if (notify) notifyListeners(this, change)
        
    }
    return true
}

未完待续

这里我们又遇到了一个class:ObservableValue,似乎target的读与改都离不了它。虽然官网有关ObservableValue的文字很少,但它的父类是大名鼎鼎的Atom,下一篇将详细分析ObservableValue在Mobx世界中究竟扮演着什么样的角色,敬请期待~