Angular中RxJS多订阅按序执行的最优实现方案
Angular路由订阅执行顺序控制问题
问题背景
查阅StackOverflow、RxJS官方资料、技术博客等多个渠道,均未找到匹配当前业务场景的解决方案。
最初在Angular组件的ngOnInit生命周期钩子中编写了如下代码:
ngOnInit(): void { this.activatedRoute.queryParams.subscribe((params: any) => { if (!!params.page) { if (params.page <= 1) this.skip = 0; else this.skip = (params.page - 1) * this.limit; } }); this.activatedRoute.params.subscribe((params: any) => { this.filter = params.filter; this.term = params.term; this.year = params.year; this.month = params.month; }); this.activatedRoute.data.subscribe((data: any) => { this.setProvider(data.route); this.loadData(data.route); }); }
核心需求
queryParams和params这两个订阅需要先完成执行、为对应公共变量赋值完成后,再触发data订阅的执行逻辑queryParams和params之间无依赖关系,二者执行先后顺序不影响最终结果
目前查到的所有示例都是多订阅间存在前后依赖、前序订阅返回值需传递给后续订阅使用的场景。但在当前场景中,Angular的代码后台同时承担ViewModel职责,仅需要前序订阅完成公共变量赋值,后续setProvider、loadData函数直接引用这些公共变量即可,不需要通过管道链式传值。
已尝试的可运行方案
方案1:链式pipe结合concatMap
该方案可正常运行,但写法看起来较为冗余——仅为了衔接管道下一环节就返回一个Observable,不确定是否存在更简洁高效的写法,代码如下:
ngOnInit(): void { this.activatedRoute.queryParams.pipe(concatMap((query: any) => { if (!!query.page) { if (query.page <= 1) this.skip = 0; else this.skip = (query.page - 1) * this.limit; } return this.activatedRoute.params; })).pipe(concatMap((params: any) => { this.filter = params.filter; this.term = params.term; this.year = params.year; this.month = params.month; return this.activatedRoute.data; })).subscribe((data: any) => { this.setProvider(data.route); this.loadData(data.route); }); }
方案2:concat操作符实现
后续尝试使用concat操作符的实现,同样可以正常运行,代码如下:
ngOnInit(): void { concat( this.activatedRoute.queryParams.pipe((q: any) : any => { let query = q.getValue(); if (!!query.page) { if (query.page <= 1) this.skip = 0; else this.skip = (query.page - 1) * this.limit; } }), this.activatedRoute.params.pipe((p: any) : any => { let params = p.getValue(); this.filter = params.filter; this.term = params.term; this.year = params.year; this.month = params.month; }), this.activatedRoute.data.pipe((d: any) : any => { let data = d.getValue(); this.setProvider(data.route); this.loadData(data.route); }) ); }
诉求
希望得到更优雅的实现建议。
内容的提问来源于stack exchange,提问作者a11smiles
相关产品推荐
相关产品推荐

