FAST 中的binding 数据流
FAST 中的binding 数据流
本文想从数据流以及设计模式的角度解析FAST 中的数据binding.
表达式
FAST 中对于动态的内容都是通过表达式来表达抽象的(x,c)=>T,这里先不讨论那些其他的类型,例如when(),等帮助函数或者一些常量表达式.因为这些例外的东西都会被FAST内部封装成表达式.
Binding的目的是为什么
Binding 的目的是为了将动态的表达式的计算结果更新到对于的DOM属性或者元素上,从而达到状态同步.然后表达式在不同的时机以及前提下,它的计算的结果是不同的.所以这边得将变化的与不变的区分开来.
- 不变的是任务就是将表达式的计算结果更新到DOM元素或者属性上,这个就被抽象成了
HTMLBindingDirective这个类.它就负责一个事情,触发执行表达式,并将执行的结果更新到DOM - 变化的是表达式的值计算的结果会随着它内部volatile的元素变化而变化
DataBinding 就是上述的变数.
数据绑定的职责是什么?它负责记录表达式在执行过程中所有的变数,同时在这些变数发生变化的时候,它需要通知HTMLBindingDirective来执行同步.所以它最重要的一个功能就是将表达式封装成一个ExpressionObserver对象,并把这个对象交给HTMLBindignDirective这个类.这样它就可以很简单的执行表达式,并且当表达式里面以来的变数发生变化的时候,HTMLBindingDirective就自动执行表达的计算及DOM的更新.
- OneWay, 单项数据流,表达式的值更新到DOM
- TwoWay, 双向数据流,表达式的值更新到DOM, 有可能DOM的更新也会影响表达式的值
- Signal, 信号量,一种手动方式触发的表达式重新计算的场景
- OneTime, 这个就是一些常量的封装.
这些不同的数据流策略对应着不同的封装,他们通过createObserver(initialSubsceiber):ExpressionObserver来约束,在不同的策略下有着不同的实现.最核心的就是对于表达式的执行过程检测的封装.这个是由ExpressionNotifierImplementation来负责的.这个类承担了多个不同的角色,所以它违背了单一职责的原则.下面一一阐述它的职责
ExpressionNotifierImplementation
- 观察表达式的执行,也就是它的
observe方法,它两个职责,- 执行表达式返回结果
- 执行表达式前,将自己设置为全局观察者(依据配置),执行结果后,还原全局的观察者
- 由于它是全局的观察者,它需要实现
watch方法,这个方法是提供给Observer.track()使用的,它会让自己去subscribe这些具体的变数. - 由于它本身是subscriber,所以它需要实现handleChange方法,这个里面就是无脑的将这个变数转发给订阅它的subscriber.例如initialSubscriber,或者后期
subscrbe()它的subscriber - 除此之外还有一些辅助系的一些方法
观察者 vs 订阅者
一开始感觉这两者好像是类似的东西,这次在FAST 的实现过程中感觉到了两者的差异.观察者观察的是一个模糊的东西,它自己也不知道改观察什么,它是提供出统一的APIwatch来让被观察的对象自己来调用. 订阅者则是,它很清楚的知道自己对什么subject感兴趣,当具体的subject发生变化的时候,通知我.总结一下两者的差异
- 观察者是吃瓜群众,它直面整个事件的发生过程,而且也只存在于整个事件的执行过程中.但是它不知道会观察到什么,只有具体的事情发生了,它才会知道.所以它的
watch是为具体的事件准备的. - 订阅者是异步的,它是提前的,在事件发生变化之前就存在.当订阅的主题发生变化,它承诺会被通知到.

浙公网安备 33010602011771号