store 是否应该保持自己的状态,并有能力在这样做时调用网络和数据存储服务...在这种情况下,这些行为只是愚蠢的信息传递者,
-或者-
...存储区是否应该是来自操作的不可变数据的哑接收者(并且这些操作是在外部源之间获取/发送数据的操作)?在这种情况下,存储区将充当视图模型,并能够在根据操作提供给它们的不可变数据设置自己的状态基础之前聚合/过滤它们的数据.
在我看来,它应该是其中之一(而不是两者的混合).如果是的话,为什么一个比另一个更受欢迎/推荐?
store 是否应该保持自己的状态,并有能力在这样做时调用网络和数据存储服务...在这种情况下,这些行为只是愚蠢的信息传递者,
-或者-
...存储区是否应该是来自操作的不可变数据的哑接收者(并且这些操作是在外部源之间获取/发送数据的操作)?在这种情况下,存储区将充当视图模型,并能够在根据操作提供给它们的不可变数据设置自己的状态基础之前聚合/过滤它们的数据.
在我看来,它应该是其中之一(而不是两者的混合).如果是的话,为什么一个比另一个更受欢迎/推荐?
我看到了flux模式的两种实现方式,在我自己完成了这两种实现之后(最初使用前一种方法),我认为存储应该是来自动作的数据的哑接收者,写入的异步处理应该在动作创建者中进行.(Async reads can be handled differently.) 根据我的经验,这有几个好处,按重要性排序:
Your stores become completely synchronous.这使得你的store 逻辑更容易遵循,也更容易测试——只需实例化一个具有某个给定状态的store ,向它发送一个操作,并判断状态是否如预期的那样发生了变化.此外,flux的核心概念之一是防止级联调度和同时防止多个调度;当你的store 进行异步处理时,这是很难做到的.
All action dispatches happen from the action creators.如果您在store 中处理异步操作,并且希望保持store 的操作处理程序同步(为了获得流量单一分派保证,您应该这样做),那么store 将需要启动额外的成功和失败操作来响应异步处理.相反,将这些调度放在动作创作者中有助于分离动作创作者和store 的工作;此外,您不必深入研究您的存储逻辑,以找出操作从何处发出.在这种情况下,一个典型的异步操作可能如下所示(根据您使用的流量的风格更改dispatch
个调用的语法):
someActionCreator: function(userId) {
// Dispatch an action now so that stores that want
// to optimistically update their state can do so.
dispatch("SOME_ACTION", {userId: userId});
// This example uses promises, but you can use Node-style
// callbacks or whatever you want for error handling.
SomeDataAccessLayer.doSomething(userId)
.then(function(newData) {
// Stores that optimistically updated may not do anything
// with a "SUCCESS" action, but you might e.g. stop showing
// a loading indicator, etc.
dispatch("SOME_ACTION_SUCCESS", {userId: userId, newData: newData});
}, function(error) {
// Stores can roll back by watching for the error case.
dispatch("SOME_ACTION_FAIL", {userId: userId, error: error});
});
}
可能在不同操作中重复的逻辑应提取到单独的模块中;在本例中,该模块将为SomeDataAccessLayer
,用于处理实际的Ajax请求.
这没什么大不了的,但很高兴拥有.如#2所述,如果你的store 有同步动作分派处理(他们应该有),你需要启动额外的动作来处理异步操作的结果.在action creators中执行调度意味着单个action creator可以通过处理异步数据访问本身的结果来调度所有三种操作类型.