2016-11-30 93 views
21

我正在寻找在单一Epic redux-observable中间件中调度多个redux动作的方式。redux-observable - 在单个史诗中调度多个redux动作

让我们假设我有以下Epic。每次发生事件时,Epic都会从后端加载数据并发送RESULTS_LOADED操作。

searchEpic = (action$) => 
    action$ 
    .ofType('SEARCH') 
    .mergeMap(
     Observable 
     .fromPromise(searchPromise) 
     .map((data) => { 
      return { 
       type: 'RESULTS_LOADED', 
       results: data 
      } 
     }) 
    ) 

现在,我们假设我需要在解决searchPromise时调度附加动作。

这样做最简单的方法似乎有第二个史诗,将听取RESULTS_LOADED并派遣第二个动作。像这样:

resultsLoadedEpic = (action$) => 
    action$ 
    .ofType('RESULTS_LOADED') 
    .map(({results} => { 
     return { 
      type: 'MY_OTHER_ACTION', 
      results 
     } 
    }) 

在这个简单的例子中,它很容易。但是,当Epics增长时,我倾向于发现自己有很多redux动作,其唯一目的是触发其他动作。此外,一些rxjs代码需要重复。我觉得这有点难看。

所以,我的问题:有没有办法在单个Epic中分派多个redux动作?

+0

ngrx/effects为基于angular2的应用程序实现此快捷方式,我不知道类似的库是否存在redux-observable? –

回答

16

没有要求您建立一对一的进/出比。所以,如果你需要,你可以使用发射mergeMap(又名flatMap)多个动作:

const loaded = (results) => ({type: 'RESULTS_LOADED', results}); 
const otherAction = (results) => ({type: 'MY_OTHER_ACTION', results}); 

searchEpic = (action$) => 
    action$ 
    .ofType('SEARCH') 
    .mergeMap(
     Observable 
     .fromPromise(searchPromise) 
     // Flattens this into two events on every search 
     .mergeMap((data) => Observable.of(
      loaded(data), 
      otherAction(data)) 
     )) 
    ) 

需要注意的是,接受一个可观察还可以接受一个承诺,阵列,或可迭代任何的Rx操作;如果它们是流,则将它们消费。所以我们可以使用数组来代替同样的效果:

.mergeMap((data) => [loaded(data), otherAction(data)]) 

您使用哪一个取决于您的个人风格偏好和用例。

+6

flatMap中的内部箭头函数的结果变量是不是数据? –

相关问题