1

Flux: Actions and the Dispatcher

原文: Flux: Actions and the Dispatcher

Flux是Facebook用于构建javascript应用的架构。它基于单向数据流。利用Flux我们将所有东西都拆分成小的组件(widgets)然后组合成庞大的应用,而Flux成功应对了所有遇到的困难。我们认为这是一种非常好的组织代码的架构,因此非常高兴能够将他贡献给开源社区。Jing Chen在F8会议上展示了Flux(youtube视频,墙内慎点),从那以后我们了解到很多人对它非常感兴趣。同时,我们公布了Flux概览与带有入门指南TodoMVC示例

Flux与其说是一整套的框架,不如说是一种模式,在React之上你只需要写很少的代码就可以开始使用它。直到最近我们都还没有公布Flux的一个重要部分:dispatcher。但随着Flux代码库Flux主页的建立,现在我们已经将dispatcher开源并与生产环境版本保持同步

Dispatcher在Flux数据流中的作用

dispatcher是单例的,在Flux应用中它被用作数据流的中央集线器。本质上它登记了一堆回调,并且按store注册回调的顺序执行。当有新的数据传入时,它向所有stores注册的回调传播此数据。调用回调的过程由dispatch方法触发,该方法接受一个数据负载对象(data payload object)作为唯一参数。

Actions 与 ActionCreators

当有新数据进入系统时,无论是通过用户交互还是web api请求,该数据会被封装成一个action——一个包含了数据字段和特别声明的action类型的对象。通常我们会新建一类工具方法的集合叫做ActionCreators,用于创建action对象并传递给dispatcher。

不同的actions用类型区分。当所有stores接收到action时,通常他们通过识别类型来决定是否响应和如何响应。在Flux应用中,stores和views都是“自治”的,他们的行为不由外部决定。actions通过store自身定义并注册的回调进入store,而不是通过类似setter之类的方法调用。

stores的“自治”消除了许多MVC框架中常见的纠结现象。传统MVC框架model间的级联更新往往会导致不稳定的状态并且使得应用难以准确测试。而Flux应用则高度解耦,并且坚守了迪米特法则:系统中的不同对象之间相互了解得越少越好。这使得软件更加可维护,可扩展,和可测试,并且更利于新团队成员理解。

flux-diagram

为什么需要Dispatcher

随着应用规模的增长,Store之间的相互依赖变得无法避免。Store A可能会需要 Store B先执行update,然后才能正确地update自己。Dispatcher可以让我们先行调用并完成Store B所注册的回调,再继续执行Store A的业务。要显式地声明这种依赖,Store需要向dispatcher表明“我要等Store B处理完了才能继续处理当前的action”。而dispatcher的waitFor方法则提供了这种功能。

dispatch方法对回调的遍历是简单、同步式的。当在执行callback过程中遇到waifFor方法时,对当前callback的调用就会中断,wairFor方法会根据声明的依赖重新确定遍历顺序(注:原文字面意思如此,但从dispatcher的源代码看是检查依赖项是否已执行,若否,则立即去执行依赖项),当所有依赖都被执行后,原先中止的callback才会继续执行

更进一步地,waifFor方法可以在同一个store回调的不同action处理分支中使用。在某种情况下Store A可能依赖Store B,而在另一种情况下又依赖Store C。在action处理语句块中使用waitFor使我们能够更细粒度地控制依赖关系。

当然也会出现问题,比如循环依赖。A依赖B然后B又依赖A这样的情况,会导致无限循环。目前Flux实现的dispatcher在遇到这种情况时会抛出一个包含错误信息的Error来警告开发者,然后开发者可以选择新建一个Store来避免这种情况。

注:从源代码看其实不用新建store,只要通过register新注册一个回调id即可,环检测是基于回调id的,Flux的官方demo中每个store有一个dispatcherToken来保存该store的回调id,事实上一个store持有多个回调id也是可行的

Chat App示例

我们和dispatcher同时公布的还有一个新的示例程序chat app ,稍微比TodoMVC的例子更复杂一点,以便于开发者能更好地理解Flux是如何解决Stores间的依赖关系以及如何调用web API的

注:这个flux-chat例子非常非常重要,store的waitFor和前置web api调用个人认为是flux理念的核心,也是store与传统MVC的Model层为何完全不同的核心

We're hopeful that the new Flux repository will grow with time to include additional tools, boilerplate code and further examples. And we hope that Flux will prove as useful to you as it has to us. Enjoy!
注:客套话懒得翻了


kpaxqin
2.4k 声望223 粉丝