原文地址:A cartoon guide to Flux - by Lin Clark



Flux在目前web开发中最受欢迎也较不被人理解,本文会以简单易懂的方式解释它。

出现问题

首先,我要声明Flux所解决的基本问题。Flux是一种帮助你处理数据的模式。Flux和React都由Facebook开发。许多人把他们放在一起用,当然你也可以单独使用它们。它们的形成是为了解决Facebook所面临的一系列典型问题。

这些问题中一个广为人知的例子就是关于通知的错误(notification bug). 当你登录Facebook时,你会通过消息图标(message icon)看到一则通知(notification)。然而你点击消息图标后,可能根本没有新消息,通知消失了。接着,在与网站进行几次交互之后,通知又回来了。你再一次点击消息图标...依然没有新消息。这个情况会在循环中继续往复发生。



这不仅仅是发生在用户里的循环,对于Facebook团队里也会有这个循环。他们修复了错误,一切在一段时间里看似表现很好,接着错误又回来了。这一直处于解决问题和再次出现问题之间来回切换。



所以Facebook在寻找跳出死循环的方法。他们不想仅仅是修复一次bug,他们希望保证系统可预测,这样他们就能确保问题不会重新出现。

根本问题

他们发现根本问题在于数据流经应用程序的方式。

住:这是我从他们的分享会上展示的简化版本中收集到的,我确定实际的架构看起来并不一样。

他们有保存数据的模型(Model),并将数据传递到视图层(View Layer)渲染。



因为用户交互发生在视图层,视图有时候需要根据用户输入来更新模型。有时模型还需要去更新其他的模型。最重要的是,这些行为有时会引发其他一系列的变化。我认为这非常有趣,因为你无法知道接下来会发生什么!(作者此处用了比喻,I envision this as an edge-of-your-seat game of Pong — it’s hard to know where the ball is going to land (or fall off the screen))



不考虑这些变化会引起异步发生的可能性。一个变化可能会一起多种其他变化。我想这就好像抛出一袋乒乓球到乒乓游戏中,随着他们飞过整个地方并穿过小径。

总而言之,它使得调试数据流变得很困难。

解决方案:单向数据流

Facebook觉得尝试一种不同的架构,数据向一个方向流动——只有一个方向——当你插入新数据时,这个流程就从头重新开始。他们称这一架构为Flux。



实际上这个技术非常棒...但你可能无法从上面这张图里看出来。

一旦你理解了Flux,这张图就显得非常清晰。问题是如果你要找到对Flux完全新的文档,我认为这张图不能帮助你理解它...这就是图应该做的事。在你开始深入了解如何做特定事情之前,图会让你对系统产生一个全面的了解。

帮助我更好理解Flux的不是这样的图,而是根据团队中不同角色要实现共同目标来考虑这个系统。所以我会想你介绍我脑子里的这些角色。

角色

在我将这些角色联系起来之前,我先对各个角色做简单介绍。

行为创建者(Action)

第一个角色是这个行为创建者。他负责创建行为,这是所有改变和交互必须经历的路径。无论你是否想改变程序的状态,或者让视图的渲染方式不同,你都需要创建行为。

我认为行为创建者就像电报员。他知道你想传递什么消息,接着再以其他系统可以理解的方式格式化信息。



行为创建者创建行为时,会伴随一个type和一个payloadtype表示你在系统中定义为行为的类型之一(通常是常量列表),比如MESSAGE_CREATEMESSAGE_READ

让系统的一部分知道所有可能的行为有一个很好的作用,那就是,当新人参与到项目里时,打开行为创建者的文件就能看到整个API——系统提供的所有可能的状态改变。

一旦创建了行为消息,行为创建者就会将该行为传递给调度人员。

调度人员(Dispatcher)

调度人员有一个大的回调(callbacks)注册表(registry),在某种程度上像电话交换机上的接线员,保留数据层(store)中需要发送的行为列表。当行为被行为创建者创建后,调度人员会将行为发送给不同的数据层。

调度人员以同步方式完成工作,如果你需要在数据层之间设置依赖关系,以便在其他数据层更新前更新,你可以让调度人员使用waitFor()进行管理。



Flux的调度人员与其他很多架构中的不同。无论行为类型是什么,它都会被发送到所有的注册数据层里。这意味着数据层不仅仅收到一些行为消息,而是接收全部消息再就实际情况过滤。

数据人员(Store)

接下来就是数据人员了。数据人员掌控这程序里所有的状态,以及状态的改变逻辑。

我把数据人员比喻成权力极大的爷,所有的状态改变必须由他亲自完成。你不能直接要求他改变状态,要请求更改状态,你必须遵循适当的步骤:通过行为创建者或调度人员提交行为。



正如我之前提到的,如果一个数据层被调度人员注册,所有的行为将会发送到那里。在数据层里,数据人员一般会用一个switch语句查看行为类型,以决定这个数据层是否关心此行为。如果数据层关心此行为,那么数据人员会根据这个行为找出需要做出哪些更改并更新状态。

一旦数据人员改变了状态,他就会提交一个改变事件,这会提示视图控制员知道状态变了。

视图与视图控制员(Controller view & view)

视图负责拿到状态并将其渲染出来给用户看,以及接收用户输入。

视图是一个展示者,他并不知道程序里发生任何事,只知道接收到的数据,以及如何将数据格式化成用户能理解的方式(通过HTML)。

视图控制员更像一个在数据人员和视图之间的中层经理,数据人员告诉他状态什么时候变了,他收集到新状态再将更新状态发送给他的子视图。

他们怎么一起工作

接下来看看这些角色怎么共同工作的。

初始化(setup)

首先有个初始化:只发生一次的程序初始化。

  1. 数据员(stores)使得调度员(dispatcher)知道,无论何时有行为(action)来了,数据员需要被通知。

  2. 视图控制员(controller views)向数据员(stores)询问最新状态(state)。
  3. 当数据员向视图控制员说明了状态后,视图控制员把这个状态告诉其子视图去渲染。

  4. 视图控制员也告诉数据员当其状态改变时记得通知自己。

    数据流(date flow)

    一旦初始化完成后,程序就准备好接收用户输入。现在,我们假设用户做改变引起了一个行为(action)。

    我们通过用户交互来启动数据流。

  5. 视图(view)告诉行为创建者(action creator)准备行为。

  6. 行为创建者格式化行为并发送给调度员(dispatcher)。

  7. 调度员按顺序将行为发送给数据人员(store),每个数据员都收到了所有行为的提示,接着数据员筛选哪些是他关心的,再相应地改变数据层状态(state)。

  8. 一旦状态改变,数据员就会让当时需要他通知的那些视图控制员知道其状态变化。
  9. 这些视图控制员会向数据员要他们更新后的状态。

  10. 在数据员给了自己更新后的状态,视图控制员就会告诉其子视图根据新状态重新渲染。

这就是我认为的Flux,希望对你有用!

译者:如有翻译错误,请指正哟,谢谢!(^U^)ノ~YO

看漫画学Flux的更多相关文章

  1. 《看漫画学Pyhton》中计算水仙花数

    利用while循环实现 i = 100 r = 0 s = 0 t = 0 while i < 1000: r = i // 100 s = (i - r * 100) // 10 t = i ...

  2. 跟vczh看实例学编译原理——三:Tinymoe与无歧义语法分析

    文章中引用的代码均来自https://github.com/vczh/tinymoe.   看了前面的三篇文章,大家应该基本对Tinymoe的代码有一个初步的感觉了.在正确分析"print ...

  3. 跟vczh看实例学编译原理——一:Tinymoe的设计哲学

    自从<序>胡扯了快一个月之后,终于迎来了正片.之所以系列文章叫<看实例学编译原理>,是因为整个系列会通过带大家一步一步实现Tinymoe的过程,来介绍编译原理的一些知识点. 但 ...

  4. 跟vczh看实例学编译原理——零:序言

    在<如何设计一门语言>里面,我讲了一些语言方面的东西,还有痛快的喷了一些XX粉什么的.不过单纯讲这个也是很无聊的,所以我开了这个<跟vczh看实例学编译原理>系列,意在科普一些 ...

  5. 看代码学知识之(2) ListView无数据时显示其他View

    看代码学知识之(2) ListView无数据时显示其他View 今天看的一块布局是这样的: <!-- The frame layout is here since we will be show ...

  6. 看日记学git摘要~灰常用心的教程

    看日记学git linux 命令行 cd ls / ls -a clear mkdir rmdir echo "hi, good day" > hi.txt touch he ...

  7. 【前端】Vue2全家桶案例《看漫画》之一、添加四个导航页

    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/vue_vux_app_1.html 项目github地址:https://github.com/shamoyuu/ ...

  8. 看漫画,学 Redux

    Flux 架构已然让人觉得有些迷惑,而比 Flux 更让人摸不着头脑的是 Flux 与 Redux 的区别.Redux 是一个基于 Flux 思想的新架构方式,本文将探讨它们的区别. 如果你还没有看过 ...

  9. 看漫画就能学SQL,简直太cool了

    对于SQl, 很多人学不会的原因是从一开始就没明白,学这东西能干啥,学会了能有什么用.甚至有些人不知道'SQL'应该怎么读,以至于一开始兴致勃勃,但是学到一半放弃了. 注意:'sql'真的不能读成'烧 ...

随机推荐

  1. 关系型数据库工作原理-时间复杂度(翻译自Coding-Geek文章)

    本文翻译自Coding-Geek文章:< How does a relational database work>. 原文链接:http://coding-geek.com/how-dat ...

  2. Injection of autowired dependencies failed

    error:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mainCo ...

  3. Spring整合Shiro并扩展使用EL表达式

    Shiro是一个轻量级的权限控制框架,应用非常广泛.本文的重点是介绍Spring整合Shiro,并通过扩展使用Spring的EL表达式,使@RequiresRoles等支持动态的参数.对Shiro的介 ...

  4. Lucene就是这么简单

    什么是Lucene?? Lucene是apache软件基金会发布的一个开放源代码的全文检索引擎工具包,由资深全文检索专家Doug Cutting所撰写,它是一个全文检索引擎的架构,提供了完整的创建索引 ...

  5. 使用python UIAutomation从QQ2017(v8.9)群界面获取所有群成员详细资料,

    首先安装pip install uiautomation, 运行本文代码.或者下载https://github.com/yinkaisheng/Python-UIAutomation-for-Wind ...

  6. TensorFlow-谷歌深度学习库 体验一二三

    一个TensorFlow的运算可以看作是一个数据流图. 一个图呢则由一组操作和数据集组成. 操作(operation)代表运算单元 数据(tensor) 代表在各运算单元流动的数据单元 要想使用一个数 ...

  7. Maven-09: 在线插件信息

    仅仅理解如何配置使用插件是不够的.当遇到一个构建任务的时候,用户还需要知道去哪里寻找合适的插件,以帮助完成任务.找到正确的插件之后,还要详细了解该插件的配置点.由于Maven的插件非常多,而且这其中的 ...

  8. Mycat 配置说明(server.xml)

    server.xml 几乎保存了所有mycat需要的系统配置信息,包括 mycat 用户管理.DML权限管理等,其在代码内直接的映射类为SystemConfig 类. user 标签 该标签主要用于定 ...

  9. [机器学习Lesson 2]代价函数之线性回归算法

    本章内容主要是介绍:单变量线性回归算法(Linear regression with one variable) 1. 线性回归算法(linear regression) 1.1 预测房屋价格 该问题 ...

  10. 深入学习Redis(1):Redis内存模型

    前言 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站高并发不可或缺的一部分. 我们使用Redis时,会接触Redis的5种对象类型(字符串 ...