Redux-Observable 中具有依赖关系的多个操作

Multiple actions with dependencies in Redux-Observable

我在 React & Redux 项目中使用 Redux-Observable Epic。我有多个动作需要发出,原来这是我一直在做的,

1) 在史诗
中抓住START_ACTION 2) 获取远程数据
3) Return 一个新的 Observanble

例如:

import fetch from 'isomorphic-fetch';
import {Observable} from 'rxjs/Observable';
import {switchMap} from 'rxjs/operator/switchMap';
import {mergeMap} from 'rxjs/operator/mergeMap';


const fetchAsync = (arg) => {
   // return an observable of promise
   return Observable::from(fetch(url + arg));
} 

export function myEpic = (action$) => {
   action$.ofType(START_ACTION)
    ::switchMap(action => {
       return fetchAsync('/action.payload')
          ::mergeMap(result => {
             return Observable::of({type: ACTION_COMPLETE, payload: result})
          }) 
    })
 };

现在如果我有另一个动作 SECOND_ACTION 需要在 START_ACTION 之后和 ACTION_COMPLETE 之前发出怎么办?换句话说,如果不确保 SECOND_ACTION 命中减速器,则不应发出 ACTION_COMPLETE

我可以编写另一个单独的 Epic 函数来执行此操作,但是还有其他更简单的方法吗?

To simplify the question, I just want to emit the SECOND_ACTION before the async.

要在执行 fetchAsync 之前发出另一个动作,您可以使用 Observable.concatstartWith 运算符,这基本上是 concat 的糖分。

export function myEpic = (action$) => {
   action$.ofType(START_ACTION)
    ::switchMap(action => {
       return fetchAsync('/action.payload')
          ::map(result => ({ type: ACTION_COMPLETE, payload: result })
          ::startWith({ type: SECOND_ACTION })
    })
 };

因为 SECOND_ACTION 同步跟随 START_ACTION,请记住,通常你应该让你的 reducer 监听 START_ACTION 而不是发出另一个动作。来自同一个动作的多个 reducer 转换状态是正常的,这也是 redux 的主要好处之一。

也就是说,在某些情况下,关注点分离肯定是更理想的,所以这更像是一个一般性提示。


上一个回答

如果您想按顺序发出两个动作,您可以将附加动作作为参数传递给 Observable.of(...actions),因为它接受任意数量的参数并按顺序发出它们。

export function myEpic = (action$) => {
   action$.ofType(START_ACTION)
    ::switchMap(action => {
       return fetchAsync('/action.payload')
          ::mergeMap(result => {
             return Observable::of(
               { type: SECOND_ACTION },
               { type: ACTION_COMPLETE, payload: result }
             )
          }) 
    })
 };

如果这不是您的意思,我深表歉意。问题不清楚。