简介
在如今的 Web 开发领域,Flux 最流行也最容易被大家所误解的技术之一。本教程打算以一种大家都能理解方式图解 Flux。
问题
首先必须先说明一下 Flux 到底解决什么问题。Flux 是一种应用处理的数据的模式。虽然 Flux 和 React 一同在 Facebook 成长起来的,很多人把它们合到一起来理解,但你仍然可以单独使用它们。它们是被设计用来解决一些 Facebook 碰到的一系列问题的。
一个众所周知的例子就是关于通知的错误。 当您登录Facebook时,您会看到通知消息图标。 但是,当您单击邮件图标时,将不会有新消息, 通知将消失。 然后,几分钟后,与该网站进行了一些互动,通知就会回来。 你再次点击消息图标…仍然没有新消息。 它会在这个循环中继续往复。
这种循环不仅仅影响了网站的用户,还包含 Facebook 的开发团队。 他们修复这个bug,好上一段时间,然后bug会回来。 周而复始,修一次,来一次。
所以Facebook正在寻找一种摆脱这种循环的方式。 他们不想一次次的修复。 他们希望使系统可预测,以确保这个问题不会重现。
深层问题
然而更深入的了解后,工程师们发现根本问题是应用数据传递的问题。
注意:这是我从他们在会谈中分享的简化版本中收集到的。 我确定实际的架构看起来不一样。
他们用Model 保存数据,并将数据传递到View
层以呈现数据。
由于用户交互是通过视图发生的,因此视图有时需要根据用户输入更新模型。 有时模型需要更新其他模型。
最重要的是,这些行为有时候会触发一连串的变化。我把这想象成一种激动人心的乒乓游戏——很难判断球的落点在哪里(或者是跑到了屏幕之外。)
我们还不能忽略这些变化可能会异步发生的事实。 一个变化可能引发多种其他变化。 我想这就是把一包乒乓球扔进你的乒乓球游戏中,他们胡乱的飞。
总而言之,它很难调试数据流。
解决方案:单向数据流
因此,Facebook决定尝试一种不同的架构,数据在一个方向上流动(只有一个方向)当您需要插入新数据时,流程会从头开始重新开始。 他们称这种架构为Flux
。
在 Facebook 的 Flux 文档中也可以找到这张图,本身要比看起来更酷,真的,非常酷……但光看上面这张图可能无法完全明白。
一旦你理解了Flux,这个图就很清楚了。 问题是,如果你对Flux完全是一个新手,我不认为这个图可以帮助你理解它……然而这就是图表应该做的。 在你开始深入了解你如何做特定事情之前,它应该让你对系统有一个全面的了解。
帮助我更好地理解Flux的并不是这样的图表,而是根据不同角色以团队形式共同实现目标的方式来考虑系统。 所以我想向你介绍我脑海中的角色。
认识一下角色
在我解释这些角色间如何交互前,先逐个介绍下它们。
Action Creator
他的第一个角色是Action Creator
。 它负责创建Action,这是所有变化和交互的喀什。 无论何时你想改变应用程序的state
,或者让View
渲染的方式不同,你需要触发一个 Action。
我认为Action Creator是电报操作员。 你带着你需要发送出的消息,找到Action Creator,它以一种其他系统可以理解的方式将你的信息进行格式化。
Action Creator使用type
和payload
(有效载荷)创建一个 Action。 该type
将是您在系统中定义的type
之一(通常是常量列表)。 一个Action的例子就像MESSAGE_CREATE
或MESSAGE_READ
。
让你系统的一部分知道所有可能的行为或许存在一个副作用。 新开发人员可以参与该项目,打开Action Creator文件并查看系统提供的整个API - 所有可能的状态更改,它们都是你的系统提供的。
一旦它创建了Action,Action Creator将该action传递给Dispatcher。
Dispatcher
Dispatcher基本上是一个巨大的回调函数注册表。 这有点像电话交换机上的电话接线员。 它保留了它需要发送Action的所有store的列表。 当动Action跑到Action Creator这儿来时,Action Creator会将Action传递给不同的store。
Dispatcher它是以同步的方式完成的,对我之前讲的多个乒乓球游戏有所帮助。 如果你需要在store之间建立依赖关系,那么你可以让Dispatcher用waitFor()
来为你管理它。
Flux的Dispatcher与许多其他体系结构中的Dispatcher不同。 无论action类型是什么,该action都会发送到所有注册的store。 这意味着store不仅仅订阅一些操作。 它听取了所有的action,并过滤掉了它所不关心的事情。
Store
接下来是store。 store可以保持应用程序中的所有状态,并且所有状态状态变化的逻辑都位于store内部。
我觉得 store 就是一个充满控制欲的长官。所有的状态变化都必须由它来亲自操作的。 所有的状态改变都必须由它自己完成。 你不能直接要求它改变状态。 store里没有setter API。 要请求状态更改,您必须遵循适当的过程…您必须通过Action Creator/Dispatcher 提交动作。
正如我上面提到的,如果store在Dispatcher中注册了,则所有action都将发送给它。 在store内部,通常会有一个switch语句来查看action的类型,以决定该store是否关心此操作。 如果商店确实关心这个动作,它会根据这个action找出需要做出哪些更改并更新的state
。
一旦sotre
对state
进行了更改,它将发出change
事件。 这将通知控制器视图状态已经改变。
Controller View 和 View
View 层负责将 state 渲染给用户,并接受用户的输入。
视图更像是一位主持人。 它不知道应用程序中的任何内容,它只知道提交给它的数据以及如何将数据格式化为人们可以理解的输出(通过HTML)。
Controller View 就像store和View之间的中间管理者。store在state改变时告诉它。 它收集新state,然后将更新后的state传递给它下面的所有View。
它们如何在一起工作?
那么让我们来看看所有这些角色如何一起工作。
开始
首先在应用启动时:应用程序初始化只发生一次。
Store 告知 Dispatcher他们希望在action产生时得到通知。
Controller View 从 Store 中获取最新的 state。
当 Controller View 接到来自 store 的 state,就将其传递给它所管辖的子 View 去渲染。
- Controller View 同时让 store 在 state 变化的时候通知自己。
- Controller View 同时让 store 在 state 变化的时候通知自己。
数据流
应用启动后,就准备好接受用户的输入了。现在我们让用户做一些操作,触发一个 action。
View 告知 Action Creator 准备一个 action。
Action Creator 做好 action 并将其发送给 Dispatcher。
Dispatcher 按照顺序将 action 传递给 store。每一个 store 都会受到所有的 action 通知,然后自行觉得是否对这个 action 做出响应,更新 state。
一旦 store 更新 state 完毕,就会告知订阅了该 store 的 controller view。
- 这些 controller view 就会向 store 请求更新了的 state。
- 从 store 中获得 state 之后,view controller 将会让它所管辖的子 view 渲染新的 state。
结尾
以上就是图解Flux,接下来请看图解Redux