最近看Flux, Reflux 和 Redux的区别时,看到一篇不错的文章A cartoon guide to Flux,就觉得有点意思,可以翻译一下加深自己的理解(后来发现好像已经有人翻译过了,不过这不重要),虽然感觉很多翻译过后感觉怪怪的。
不废话了-----------
图解Flux
Flux 不仅是目前前端开发中最流行的也是最不易懂的话题之一。这篇文章想用最简单的方式让大家懂得什么是Flux。
Flux解决的问题
首先,我要解释一下Flux解决的问题。 Flux是一种在app中处理数据的模式。 Flux 和 React在Facebook一起长大。 许多人都将他们一起使用,其实它们可以相互独立的使用。它们是为了解决Facebook看见的一系列问题而被开发出来的。
这一系列问题中的一个知名例子是消息通知的bug。当你登录Facebook,你可以看到消息图标上有数字表示有新消息。当你点击消息图标,消息通知数字会消失,表示没有有新消息了。或许几分钟之后,与网站进行了几次交互后,通知就会回来。 你会再次点击消息图标,直到没有新消息。这将继续在这来回循环♻️...
这不只是在网站上用户遇到的循环问题。Facebook team也遇到了这样的问题。他们修复了一个bug,一段时间内都能正常工作,过一段时间bug又回来了。他们会在问题被修复和问题重现之间来回循环♻️.
所以Facebook寻找了一种方法来解决这个循环问题。他们不想只是修复问题,而是让系统有可预测性,这样他们就可以保证问题不会再继续出现。
根本问题
他们定义的根本问题是数据在app中传递的方式。
Note: 这是我在他们在演讲中分享的最简单的版本。我不确定真实的版本是否有所不同。
这些持有数据的model会将数据传递给view层让view层来渲染这些数据。
因为用户通过view来进行交互,所以有时view需要根据用户输入来更新model。有时一些model需要去更新其他model。
除此之外,有时这些行为会触发一连串的变化。我将这想象为乒乓球游戏,很难知道球最终会落在哪里。
请注意这些变化可能是异步发生的。一个变化可能触发多个变化。我觉得这就像将整袋乒乓球扔出去一样,它们到处乱飞。
总的来说,很难去debug数据流。
解决方法:单向数据流
所以Facebook决定尝试一种不同的架构,在这种架构中数据单向传递-单向数据流-当你需要插入新的数据,这个流完全从头开始。他们称这种架构为Flux.
这是很棒的… 但是也许你没办法从上图中看出来它到底是什么。
一旦你理解了Flux,这个图就相当清晰。问题是如果你对Flux的理解完全是新的,我认为这个图并不能帮助你理解它。这是图应该做的,它应该在你真正开始着手去了解它怎么做具体事情之前能让你对系统有一个全面的了解。
能帮助你更好的理解Flux的不是这样的图,而是通过思考构成这个系统的不同特征,它们是怎么一起工作来完成这个目标的。接下来我会向你介绍我脑中的一系列特征。
详解特征
在我开始解释它们是怎么相互作用之前,简单介绍一下这些特征。
Action creator
第一特征是action creator。它负责创建action,这是所有变化和交互都应该通过的路径。不论是你想改变app的状态,还是让view渲染不同的东西,你都得发送一个action。
把action creator看作一个电报员。当你去到action creator时,你已经基本知道你要发送的信息是什么了,然后action creator把信息按整个系统都能理解的方式格式化。
action creator 创建一个有type和payload的action。Type是你在系统里已经定义好的某一种action(通常是产量列表)。一个action的例子可以像
MESSAGE_CREATE
或者
MESSAGE_READ
。
这有一个好的副作用,系统的一个部分会知道所有可能的action。一个新加入项目的开发者,打开action creator的文件,查看所有的API — 系统提供的所有状态的改变。
一旦创建好一个action,action creator会将这个action 传递给dispatcher。
Dispatcher
Dispatcher 是一个callback的注册表。它像一个电话总机的电话接线员。 它持有需要发送action的所有store的列表。当一个action从action creator来,它会将action 传递到不同的store去。
它异步的进行,能帮助解决前面我说的多个乒乓球问题。如果你还需要建立store间更新顺序的依赖,你可以让dispatcher通过waitFor()
帮你管理。
Flux dispatch和其他架构的dispatcher不同。不论action 的type是什么类型,每个action都会发送到所有注册过的store中。这意味着store不是订阅了一些action,而是监听所有的action,然后过滤出它们关心的action。
Store
接下来是store。store持有app中所有的状态,并且所有的状态改变的逻辑都在store中。
我觉得store就像一个过度控制的官僚。所有的state都得通过它来改变。并且你不能直接请求让它改变state。store没有setter方法,想要改变某个state,你必须遵循适当的程序。你必须通过action creator或者dispatcher pipeline提交一个action。
如我前面提到的,如果store在dispatcher中注册了,所有的action都会发送给它。store中,通常会通过switch
查找action type来决定这个action是不是这个store关心的。如果是,它会根据这个action来计算state需要做哪些改变,并更新state。
一旦store改变了state,它会发射一个改变事件。这个会通知controller view 这个state改变了。
The controller view and the view
View主要负责取状态,并将状态渲染为可视化的图形界面给用户看,同时也接收用户输入。
View是一个演播员。它不清楚app中的任何事情,只知道交给它的数据,然后怎样将这些数据格式化为用户可以理解的输出(通过HTML)。
Controller view 是store 和 view中间的管理者。当状态改变时,Store会告诉它。 它则收集新的state,并将所有更新过的state传递给它下面的所有子view。
它们是怎么一起工作的
让我们来看看这些特征是怎么一起工作的。
准备
首先setup,app 初始化,只会发生一次。
-
Store让dispatcher知道当action来了,它们想被通知到。
- 然后controller view会向store询问最新的状态。
-
当store把最新的state给controller view时,它们会将state向下传递给它们的子view去渲染。
-
Controller view也要求store,只要state有变化就持续通知它们。
数据流
一旦准备完成,app就已经准备好接收用户输入。那让我们通过让用户做出改变来触发一个action。
我们将用用户交互启动数据流。
-
View 告诉action creator 准备一个action.
-
Action creator 格式化action,然后将它发送给dispatcher。
-
Dispatcher将action按顺序发送给store们。每个store得到所有action的通知。然后store决定是否需要处理这个action,相应的去改变state。
- 一旦改变state完成,store让订阅了自己的view controller们知道state改变了。
-
这些view controller们会询问store给它们更新后的state。
-
在store给了它state,view controller将会告诉它的子view根据新的state重新渲染。
这就是我对Flux的理解,希望对你有用:)
Resource:
A cartoon guide to Flux