在RxJS中如何链式调用数量不固定的多个Observables?
解决方案
你这个动态次数链式调用的场景,直接用RxJS内置的expand操作符就能实现,它专门处理递归生成Observable的需求,完全可以替代你现在的嵌套订阅写法,通用性也足够。
基础实现(只取最终查询结果)
首先导入所需依赖:
import { EMPTY } from 'rxjs'; import { expand, last } from 'rxjs/operators';
业务调用代码:
// 替换为你第一次调用需要传入的初始parent_id const initialParentId = '你的初始父节点ID'; this.myService.getNodeById(initialParentId).pipe( // 接收上一次请求的返回结果,判断是否需要继续调用 expand(res => { // parent_id存在就继续发起查询,否则返回EMPTY终止递归 return res.parent_id ? this.myService.getNodeById(res.parent_id) : EMPTY; }), // 只保留递归终止后最后一次请求的结果,不需要的话可以去掉这行 last() ).subscribe(finalNode => { // 这里拿到的就是递归到没有parent_id的最终节点 console.log('最终查询结果:', finalNode); });
扩展实现(收集所有查询到的节点)
如果你需要拿到每次递归查询的所有节点,只需要把last操作符换成toArray即可:
import { EMPTY } from 'rxjs'; import { expand, toArray } from 'rxjs/operators'; this.myService.getNodeById(initialParentId).pipe( expand(res => res.parent_id ? this.myService.getNodeById(res.parent_id) : EMPTY), toArray() ).subscribe(allNodes => { // allNodes为按调用顺序排列的所有节点数组 console.log('所有查询到的节点:', allNodes); });
方案优势
- 完全适配你当前使用的RxJS 6.6.0版本,无需升级依赖
- 没有嵌套订阅的回调地狱问题,逻辑全部链式声明,可读性和可维护性更高
- 通用性强,只要修改
expand内的判断条件和返回的Observable,就能适配任意动态次数的链式调用场景 - 错误处理逻辑和普通Observable调用一致,直接在pipe中添加
catchError即可统一处理请求异常
内容的提问来源于stack exchange,提问作者Ninroot
相关产品推荐
相关产品推荐

