redux-observable - 在单个史诗中发送多个redux动作

dot*_*ral 34 rxjs redux redux-observable

我正在寻找在单个Epic redux-observable中间件中调度多个redux动作的方法.

我们假设我有以下史诗.每次SEARCH事件发生时,Epic都会从后端加载数据并调度RESULTS_LOADED操作.

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

现在,让我们假设我需要在searchPromise解决后调度其他操作.

这样做的最简单的方法似乎是第二个史诗,它将听取RESULTS_LOADED并发送第二个动作.像这样:

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

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

所以,我的问题是:有没有办法在一个Epic中发送多个redux动作?

pau*_*els 37

不要求您进行一对一的输入/输出比率.因此,如果需要,您可以使用mergeMap(aka 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))
        ))
    )
Run Code Online (Sandbox Code Playgroud)

请注意,任何接受Observable的Rx运算符也可以接受Promise,Array或Iterable; 消费它们 - 如果它们是溪流.所以我们可以使用数组代替相同的效果:

.mergeMap((data) => [loaded(data), otherAction(data)])
Run Code Online (Sandbox Code Playgroud)

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

  • 如果flatMap中的内部箭头函数中的结果变量不是数据吗? (6认同)