【问题标题】:How to chain actions and epics?如何链接动作和史诗?
【发布时间】:2017-11-14 15:29:54
【问题描述】:

我熟悉 React 和 Redux,但对 RxJS 和 redux-observable 很陌生。

我正在处理一个我已经设法解决的流程,看起来像这样:

const reducer = (state, action)  => {
   switch(action.type) {
   // some other cases here
   case Types.LOCATION_GEOCODED: 
      const { address, place_id } = action
      return {...state, address, place_id }
   }
}

const updateLocationEpic = (action$, store) =>
   action$.ofType(Types.UPDATE_LOCATION)
   .mergeMap((action) =>
      Observable.fromPromise(reverseGeocode(store.getState().location))
      .map(({address, place_id}) => ({type: Types.LOCATION_GEOCODED, address, place_id}))
   )

const broadcastLocationEpic = (action$, store) =>
   action$.ofType(Types.LOCATION_GEOCODED)
   .map((action) => ({type: Types.NEW_CURRENT_LOCATION, store.getState().location}))

第一个史诗在异步请求之后发出 LOCATION_GEOCODED 动作,reducer 然后“完成”位置信息,最后第二个史诗从状态中获取完整的位置并广播它。 p>

关键是确保 NEW_CURRENT_LOCATION 动作在 reducer 处理了上一个动作 (LOCATION_GEOCODED) 之后触发,因为它需要查询刚刚更新的状态。

上面的代码有效,但我想知道它是否可以以某种方式在单个史诗上表达,特别是因为我有另一种情况,我需要等待并行请求产生的两个动作,所以我需要做点什么类似于您使用 Promise.all 类型的模式所实现的效果

有没有更好的方法在单个史诗上执行此操作?

【问题讨论】:

  • 您的map 是否仅在您的问题中打错电话?例如其中一个map(({address, place_id}) => {type: Types.LOCATION_GEOCODED, address, place_id}) 是一个解析错误返回的对象需要用括号括起来。这也几乎可以肯定是一个错字:{type: Types.NEW_CURRENT_LOCATION, store.getState().location} 这不是一个解析错误,但实际上创建了一个带有标记语句的块,然后是一个无关调用以获取该状态,没有返回值。完全不是你想要的:)
  • 打错字了,抱歉。在实际示例中,我使用 reduxsauce 并调用 creator 函数,考虑只放置计划对象以使其更简单。我将修复示例

标签: redux-observable


【解决方案1】:
const updateLocationEpic = (action$, store) =>
    action$.ofType(Types.UPDATE_LOCATION)
        .mergeMap((action) => Observable.merge(
            Observable.fromPromise(reverseGeocode(store.getState().location))
                .map(({ address, place_id }) => ({ type: Types.LOCATION_GEOCODED, address, place_id })),

            action$.ofType(Types.LOCATION_GEOCODED)
                .map((action) => ({ type: Types.NEW_CURRENT_LOCATION, location: store.getState().location }))
        ));

【讨论】:

  • 这是否意味着我们需要为每个中间结果创建另一个动作类型?是否可以让以后的进程重用以前的值而不专门为此调度一个动作?
  • 是的,您需要对每个中间结果进行操作,您可以使用具有不同参数的相同操作,如果对您更有效,可以使用参数filter。
猜你喜欢
  • 2018-01-20
  • 2021-01-11
  • 2016-03-05
  • 1970-01-01
  • 2020-07-29
  • 2017-03-17
  • 1970-01-01
  • 1970-01-01
  • 2019-02-14
相关资源
最近更新 更多