如何在redux-observable Epic中执行2个异步调用并分别分发结果
嘿,刚接触RxJS确实会对操作符的组合有点懵,我来帮你理清楚这个场景的处理方式~
首先,你选switchMap完全没问题!因为你提到这是初始化数据,新请求进来时没必要保留旧请求——switchMap的核心就是当新的源Observable(这里就是新的PROCESSDATA action)触发时,自动取消之前还在进行的订阅,刚好匹配你的需求。
接下来看怎么处理“请求两份数据,拿到每份后分发对应action”的逻辑,分两种常见场景给你示例:
场景1:两份数据请求并行发起(更高效,适合无依赖的独立数据)
如果两个请求之间没有依赖关系,用merge让它们并行执行,每个请求完成后立刻分发对应的action:
const processDataEpic = (action$) => { return action$.ofType(PROCESSDATA).pipe( switchMap(() => { // 并行发起两个请求,各自完成后分发对应成功action return merge( fetchData1().pipe( map(data1 => fetchData1Success(data1)), catchError(err => of(fetchData1Failure(err))) // 别忘了处理错误 ), fetchData2().pipe( map(data2 => fetchData2Success(data2)), catchError(err => of(fetchData2Failure(err))) ) ); }) ); };
场景2:两份数据请求串行发起(适合第二个请求依赖第一个的结果)
如果第二个请求需要用到第一个请求的返回值,就用concatMap或者switchMap嵌套来实现串行:
const processDataEpic = (action$) => { return action$.ofType(PROCESSDATA).pipe( switchMap(() => { // 先请求第一份数据,分发action后再发起第二份请求 return fetchData1().pipe( map(data1 => fetchData1Success(data1)), catchError(err => of(fetchData1Failure(err))), concatMap((data1) => // 这里可以用data1作为第二个请求的参数 fetchData2(data1.id).pipe( map(data2 => fetchData2Success(data2)), catchError(err => of(fetchData2Failure(err))) ) ) ); }) ); };
关键细节提醒
- 错误处理:一定要给每个请求加上
catchError,避免单个请求失败导致整个Epic崩溃,同时可以分发错误action到store里做后续处理。 - switchMap的作用:它会帮你自动清理旧请求——比如用户连续触发两次
PROCESSDATA,第一次的请求还没完成时,第二次触发会直接取消第一次的请求,只保留最新的请求,完全符合你“初始化数据不需要旧请求”的要求。
内容的提问来源于stack exchange,提问作者user2047485
相关产品推荐
相关产品推荐

