如何简化使用mergeMap的嵌套HTTP顺序调用?
顺序调用多个HTTP请求的简洁实现方式
你当前通过嵌套mergeMap在epic中顺序触发多个API请求的方式虽然可行,但确实有更简洁的写法。forkJoin是并行执行请求,不符合你的顺序需求,以下是两种更优的实现方案:
方案一:链式concatMap替代嵌套mergeMap
concatMap会严格等待前一个Observable执行完成后再触发下一个,完全匹配你的顺序执行需求,链式写法比嵌套结构更清晰易读:
export const deleteEverything = (action$, _) => action$.pipe( actionOfType(delete.request), concatMap(({ payload: { id }}) => unpublishAbcApi(id).pipe( concatMap(() => deleteDefApi(id)), concatMap(() => deleteGhiApi(otherId)), concatMap(() => deleteJklApi(id)), map(() => ({ id })) ) ), concatMap(({ id }) => { // 这里处理成功逻辑,比如dispatch成功action }), catchError(error => { // 全局错误处理 }) );
方案二:用concat批量执行请求
如果你的请求之间没有数据依赖(仅需要按顺序执行),可以把所有请求包装成Observable数组,通过concat操作符按顺序执行,写法更简洁直观:
import { concat, last } from 'rxjs'; export const deleteEverything = (action$, _) => action$.pipe( actionOfType(delete.request), concatMap(({ payload: { id }}) => concat( unpublishAbcApi(id), deleteDefApi(id), deleteGhiApi(otherId), deleteJklApi(id) ).pipe( // 取最后一个请求的结果作为输出,若要收集所有结果可改用toArray() last(), map(() => ({ id })) ) ), concatMap(({ id }) => { // 处理成功逻辑 }), catchError(error => { // 错误处理 }) );
关键说明
- 两种方案均保持顺序执行的行为,和你原有的嵌套
mergeMap逻辑完全一致 - 任意请求失败时,
catchError会立即捕获错误并终止后续请求,和原逻辑一致 - 方案二中的
last()用于获取最后一个请求的结果,若需要收集所有请求的返回值,可替换为toArray()操作符
内容的提问来源于stack exchange,提问作者bdobry
相关产品推荐
相关产品推荐

