首页 > FLUX中异步请求应不应该放Store中?

FLUX中异步请求应不应该放Store中?

个人认为是应该放在Action Creator层的,但是时常会见到由Store负责API请求的flux实现。

之前我以为这是很多人受MV*的Model影响,把Store也当作了面向Server的数据代理

但是随着越来越多的见到这种用法。甚至上上周六在UPYUN举办的线下活动中,豆瓣的著名大牛@张克军 前辈在流程图中也将API调用交给了Store,如下图:

当前最流行的FLUX实现reflux的推荐示例react-news也将异步的数据操作放在了store中。

与此同时,Facebook的态度似乎有一些摇摆:

在在React官网的Blog中,有这么一篇介绍Flux的文章:Flux: Actions and the Dispatcher,其中出现的配图如下:

上图的观点很明显:API请求应该由Action Creator负责

然而,在后来FLUX官网的“整理版”同名文章中,却去掉了上图,取而代之的是没有标注Web API的流传的最广的那张流程图。这实在是有些另人费解。

从个人的理解而言,Store代表了整个应用的当前状态。而Action则代表了对整个系统的输入,即可能改变应用状态的两类行为:

由于API操作可能会改变应用状态,他应该以Action的形式输入FLUX系统,而不是被Store内部消化。

当Store不包含异步逻辑时,对每一次Action输入,Store的变更都是确定的,整个应用也因此变得更加可预测,action输入--dispatcher分发--store处理--视图渲染也是非常完美的单向数据流动。

而如果在Store中发起API请求,每次请求至少有成功与失败两种状态,级联时可能状态更是指数上升。如果每次action产生的状态变更是无法确定的,FLUX反复强调的可预测和单向数据流要如何体现呢?

最后的总结下问题:

  1. FLUX中异步请求应不应该放Store中?
  2. 如果应该放在Store中,为什么?

@题叶 我看到你在Flux的issue中有过相关问题和讨论,最后结果似乎也是更应该放在Store之外?


我是这样理解的:
   第一:把store看成是前端的数据源包括状态缓存,那么ajax获取数据相关的请求,就应该是满足和完善数据源的,那么就应该放入store.
   第二:View 跟着 Store 更新,而ajax是操作Store的,view触发的action,action引入Store的更新。action更多的是传递与注册。业务相关数据逻辑与业务(非所有逻辑,eg:验证)应该由store去完成,如果把ajax看做数据业务部分,自然应该放入store.
   


我们在简聊的实践当中 Ajax 是放在 Action Creator 大致的位置的.

我倾向于这样去理解:
一个应用有 Store, 有 View,
View 跟着 Store 更新, View 上的 Action 会引起 Store 的更新.
当出现网络请求的时候, 问题不是网络请求是哪个部分, 而是为什么需要网络请求?
更全局的看法是, 服务器上的数据库是 Store, 前端的界面是 View,
因为当前技术的限制, Store 和 View 之间有巨大的延时, 只能在前端缓存一份 Store.
这样理解, 我认为网络请求是发送 Action 到 Store 的一个过程,
对应在 Action Creator 当中做处理.


我们换一个问题讨论吧。如果当remote response不是来自于ajax请求,而是来自于websocket, 这时候action creator和store哪个合理?


大部分数据的唯一真相(SSoT)在后端,前端的Store只需要也只应该把后端的数据显示出来,作为缓存之类。
为了显示这类数据而做的请求可以放在Store里面,因为是不应该失败的请求。
同意你的其他观点。


首先,不是所有对数据的请求都是要通过 Store 的。无需在 Components 之间重用的数据,则可以让 Component 自己去获取,例如:搜索时的 Auto Complete 数据查询。这种 sideway 数据未来的获取方法的讨论在 https://github.com/facebook/react/issues/3398。
需要在 Components 之间分享的数据,则可以通过 Store 来获取,反过来通过事件通知 Component。
如果不仅想获取数据,而且也要获得调用失败的状态,那么定义专门表示错误状态的事件虽然可行,但是却会造成 Component 内的订阅代码冗余和状态混乱。
Reflux 解决这个问题的方法是,用 action 模拟 Promise。Component 可以用 someAction.triggerPromise().then/.catch 这样的方式来触发 action,获得结果或者获得错误。Store 则负责监听 someAction,获得数据后调用 somaAction.completed(result)触发代表成功的 someAction.completed (这其实也是一个 action);失败了则触发 someAction.failed。Reflux 负责将这三个 actions (实际是三个有父子关系的事件类型) 通过 triggerPromise 包装成了 Promise。
Reflux 可以包含支持 Flux 的模式(例如,Store trigger event 来通知数据变化),但是并不限定死调用模式,遇到更多需求的时候,其灵活性要强得多。因为其本质是一套 Pub/Sub 系统,但是添加了一定程度的模拟 RPC 的语法糖,以及 React 的 Mixins。

【热门文章】
【热门文章】