【问题标题】:redux-observable - dispatch multiple redux actions in a single epicredux-observable - 在单个史诗中调度多个 redux 操作
【发布时间】:2017-04-14 16:12:28
【问题描述】:

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

假设我有关注 Epic。每次SEARCH事件发生时,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 操作?

【问题讨论】:

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

标签: javascript redux rxjs redux-observable


【解决方案1】:

或者也许你有三个动作,

API_REQUEST, API_RUNNING, API_SUCCESS,

searchEpic = (action$) => 
action$
.ofType('API_REQUEST')
.mergeMap((action) => {
   return concat(
       of({type: 'API_RUNNING'}),
       Observable.fromPromise(searchPromise)
        .map((data) => {
          return {type: 'API_SUCCESS', data}; 
        }),
    );
});

【讨论】:

    【解决方案2】:

    没有要求您设置一对一的输入/输出比例。因此,如果需要,您可以使用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))
            ))
        )
    

    请注意,任何接受 Observable 的 Rx 运算符也可以接受 Promise、Array 或 Iterable;消费它们,就好像它们是溪流一样。所以我们可以用一个数组来代替同样的效果:

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

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

    【讨论】:

    • flatMap中内箭头函数的results变量不应该是数据吗?
    猜你喜欢
    • 2018-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-12
    • 2019-02-24
    • 2021-11-13
    • 2019-01-23
    • 2017-04-22
    相关资源
    最近更新 更多