redux-observable - 在单个史诗中调度多个 redux 操作

Posted

技术标签:

【中文标题】redux-observable - 在单个史诗中调度多个 redux 操作【英文标题】:redux-observable - dispatch multiple redux actions in a single epic 【发布时间】: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 的类似库? 【参考方案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变量不应该是数据吗?

以上是关于redux-observable - 在单个史诗中调度多个 redux 操作的主要内容,如果未能解决你的问题,请参考以下文章

如何在 redux-observable 史诗中链接 RxJS 可观察?

Redux-Observable 测试只读史诗

为啥我的 redux-observable 史诗没有被触发?

React redux-observable:以史诗般的方式进行顺序 API 调用

从 redux-observable 的史诗有条件地调度额外的动作

redux-observable 无法从发出的动作中捕获错误,错误会停止动作流