【问题标题】:Flux store dependency with async actions具有异步操作的通量存储依赖项
【发布时间】:2016-02-11 22:31:12
【问题描述】:

我无法理解使用 Flux 模式执行此操作的最佳方法是什么。例如,假设我有一个userStore,我会听它。一旦更改,我需要获取user.name 并访问colors[user.name] - 但colors 对象来自我拥有的另一个colorsStore 商店。这是它的精髓:

var self = {};
userStore.addListener(function(user) {
  // dependency with the colors store
  var color = self.colors[user.name]
})
colorsStore.addListener(function(colors) {
  self.colors = colors;
})

actions.getUser() // modifies userStore
actions.getColors() // modifies colorsStore

问题在于这两个操作是异步的(例如,它们从 AJAX 调用中获取数据)。考虑到这一点,userStore 可能会在从其他商店填充 self.colors 变量之前发生变化。

这是如何使用 Flux 模式处理的? Dispatcher 对此有帮助吗?抱歉,我是 Flux 模式的新手。直观地说,我会简单地以适当的顺序调用异步操作,例如:

actions.getColors() // need to populate self.colors before running getUser()
  .then(actions.getUser())

但想知道是否有更 Flux 的方式来做到这一点。

【问题讨论】:

  • 为什么没有一个通用的 onChange 函数,您可以从这两个侦听器中调用它?检查颜色是否已经设置..如果没有,则在用户进入时设置用户..当颜色进入时,您有颜色和用户,以便您可以正确访问它
  • 你考虑过使用 promise 吗?这听起来像是 promise.all 的经典用例
  • colorsStore.colors 会改变吗?其他组件是否使用colorsStore.colors。
  • @JanakaStevens 是的,是的。
  • 是否只是连接的两个商店的初始 ajax 调用?

标签: javascript reactjs flux


【解决方案1】:

从通量的角度来看,您的设置很好。 您的组件需要能够处理由您的操作生成的不同可能(存储)状态,其中可能包括:

  • 用户存储有旧数据/无数据,颜色存储已有最新数据
  • 用户存储有最新的用户数据,颜色存储仍有旧数据

如果您希望这些状态中的任何一个以某种方式对用户可见(例如显示加载指示器,在等待最新颜色时显示旧颜色/默认颜色),那么 react-flux 方法就是处理这些状态在你的组件内部。

如果您不想向用户显示有关这些状态的任何信息,您有两种选择:

  • 在您的组件内部,从 colorStore 侦听器函数内部触发 actions.getUser()(快速而肮脏的解决方案)
  • 更改设置以防止不需要的存储状态触发组件更新

对于第二种解决方案,您通常可以这样做:

  • 您的组件是否触发了这两个操作
  • 两个监听器触发相同的函数getStateFromStores()
  • 此函数从两个存储中获取状态,并且仅当用户和颜色匹配时才更新组件 (setState())

这样,您的异步调用可以按任何顺序返回。

【讨论】:

  • 为什么投反对票?您能否提供反馈,以便我改进答案?
【解决方案2】:

如果我正确理解了您的问题,您可以在这种情况下使用waitFor。还有关于"waitFor vs combining stores into one"的讨论,所以合并商店也可以解决你的问题。

【讨论】:

  • 谢谢,waitFor 确实有意义,但是上面的代码存在于 UI 级别(我正在侦听存储更改并且无权访问调度程序)。此外,我不希望我的商店等待其他商店,因为它们仅在此特定视图中捆绑在一起 - 这就是我将逻辑放在商店侦听器中的原因。任何想法?不确定我是否理解“组合商店”的概念。这将如何运作?
  • waitFor 结构是(AFAIK),用于使一个商店在 1 次调度后等待另一个商店。如果我理解正确,您的案例是关于以特定顺序处理 2 个调度(2 个 ajax 响应)。在这种情况下,waitFor 将无济于事,或者至少需要一个需要更多说明的特殊实现。
  • @wintvelt waitFor 不对。如果您有用户个人资料页面并且需要加载用户信息,例如通知,您可以创建一个操作“loadUserProfile”,并且 2 个存储(例如“配置文件”和“通知”)将处理该操作。无论如何,这绝对取决于您的目的,在一种情况下它可以工作,而在另一种情况下 - 不要。
  • waitFor 适用于 1 次分派到 2 家商店(如在您的示例中,1 条消息同时包含配置文件和通知)。这种情况是不同的:有 2 个 Ajax 调用 + 响应,所以 2 个调度,每个用于不同的存储。据我所知,WaitFor 没有解决这个问题。
猜你喜欢
  • 2016-04-22
  • 2020-02-16
  • 2020-10-30
  • 2015-06-24
  • 1970-01-01
  • 2014-01-09
  • 1970-01-01
  • 1970-01-01
  • 2014-06-18
相关资源
最近更新 更多