商店应该保持自己的状态并能够调用网络和数据存储服务……在这种情况下,这些动作只是愚蠢的消息传递者,
-要么-
…商店应该是动作中不可变数据的愚蠢接收者(而动作是在外部源之间获取/发送数据的动作吗?在这种情况下,商店将充当视图模型,并且能够聚合/过滤它们的数据根据动作所馈送的不可变数据来设置自己的状态之前。
在我看来,它应该是一个或另一个(而不是两者混合)。如果是这样,为什么一个偏爱/推荐另一个偏爱?
我已经看到了两种方式都实现了通量模式,并且我自己都做完之后(最初采用了前一种方法),我认为存储应该是动作中数据的愚蠢接收者,并且异步处理写操作应该存在于动作创作者。(异步读取的处理方式可能有所不同。)以我的经验,按重要性顺序,它有一些好处:
您的商店将完全同步。 这使您的商店逻辑更易于遵循和测试,非常容易-只需使用某种给定状态实例化商店,向其发送操作,然后检查状态是否按预期更改。此外,流量中的核心概念之一是防止级联调度并一次阻止多个调度。当商店进行异步处理时,这很难做到。
所有动作分派均由动作创建者执行。 如果您在商店中处理异步操作,并且希望使商店的动作处理程序保持同步(并且应该为了获得通量单次派发保证),则商店将需要触发其他SUCCESS和FAIL动作以响应异步处理。相反,将这些调度放到动作创建者中有助于将动作创建者和商店的工作分开;此外,您不必深入研究商店逻辑即可确定从何处调度操作。在这种情况下,典型的异步操作可能看起来像这样(dispatch根据您使用的助焊剂的风味更改调用的语法):
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请求。
SomeDataAccessLayer