在上篇中写了对flux的分析,这次来说说reflux吧。reflux是对flux的升级扩展,并且去掉了dispatcher这一层,比起使用起flux来,思路更加清晰,是一个标准的pub/sub模式的架构,同时能少写很多代码。这次我还是通过reflux的todoMvc来解释reflux的用法。
reflux介绍
reflux保留了flux中action
,store
,单向数据流
这三个概念。我们主要来看下有哪些不同:
- 移除了单例的dispatcher,用action来代替
- store可以监听action的行为,无需进行冗余的switch判断
- store可以相互监听,可以进行进一步的数据聚合操作,类似于map/reduce
waitFor
被连续平行的数据流所替代
整个过程大致是这样的
|
|
store监听action的行为,当页面上有操作触发action的时候,emit
一个action
事件,store监听到事件后执行store中的callback处理相应的逻辑,同时trigger
出另外一个change
事件,view通过监听store的变化,来执行setState,从而达到页面重新render更新。下面我们来具体看下todoMvc这个例子的具体实现吧。
Action的创建
首先是action的创建,可以通过createActions
的方式,创建所有应用中可能用到的action。
|
|
这里返回的是一个actions
对象,里面包含了各个actionName及其对应的functor
函数,而此时的functor
已经继承了各种pub/sub
的私有方法,方便后面使用。
如果说想创建单个的action,也可以使用createAction
方法,这个是直接返回了一个functor
。
Store到Action的订阅
通过createStore
方法来创建store,并且用on
加 actionName 的方式添加各个action的回调函数。
|
|
使用listenables: [TodoActions]
来添加action和callback的绑定,推荐使用这种方式来做绑定。同时你也可以使用listenTo
或者listenToMany
方法对action做逐个绑定。在createStore内部存在一个Store
构造函数,首先把所有回调函数赋值到构造函数的this
对象上,通过listenToMany
方法逐一对actionName做callbackName化(加 on 处理),然后在this
对象上找到action所对应的回调函数,然后调用listenTo
方法。传入到listenTo
内部的listenable
参数,其实就是我们前面提到的functor
函数,在它上面已经绑定了listen
这个私有方法。此时调用listen
方法来添加addListener
的监听,这样就完成了store到action的监听。
Action到Store的发布
在view组件中,通过鼠标事件或者是键盘操作触发action的执行。
|
|
我们通过click事件触发了一个action的删除操作。这里的TodoActions
是前面提到的actions对象,TodoActions.removeItem()
执行了functor
函数。
|
|
最终在trigger
函数内部实现了事件的emit,这样就完成了action到store的事件发布。每次操作action就会执行store中对应的回调函数。
Store到View的发布
上面介绍了action和store之间的关系,下面来说说store和view之间的关系。这两者之间也是种pub/sub模式。不知道你注意到没,在store中的每个回调最终都会调用updateList
函数内部的this.trigger()
方法。如注释写的,他是用来通知监听了store的组件,list被更新了。
|
|
这里this
指向Store构造函数,trigger
函数其实是emit了一个change
事件。找到了发布者,我们再来看看订阅者。
View到Store的订阅
在view中通过mixins的方式,添加了view对store的监听。当有数据发生变化的时候,调用setState方法修改state的状态,重新渲染组件。
|
|
这样我们就完成了上图中所有的流程。
小结
与flux比起来,store与view之间的关系是一样的,都是通过controller-views来监听store的数据变化,当有数据变动后emit一个事件出来,view监听到事件后,修改state的状态来重新render更新页面。区别在于action与store之间个关系,flux通过dispatcher这个中间者来分发action和store之间的数据,reflux则是直接让action和store互相关联,省去了分发者这个角色。
对于flux来说,dispatcher也不是多余的存在,可以看下官网的解释。假设存在storeA和storeB,其中A又依赖了B,所以需要通过dispatcher提供的waitFor()
方法来先执行storeB,dispatcher也确保了同一时间只能执行一个action,同时也规避了A依赖B,而B又依赖A这样循环依赖的存在。
篇幅有限,还有很多都没涉及到讲,可以看下下面参考链接里的内容。讲完了flux和reflux的介绍,下次再来讲讲redux的介绍。
参考
http://blog.krawaller.se/posts/react-js-architecture-flux-vs-reflux/
http://blog.krawaller.se/posts/reflux-refinement/
http://www.cnblogs.com/lovesueee/p/4893218.html
http://segmentfault.com/a/1190000002793786?utm_source=tuicool#articleHeader16