[英]How to chain api calls using rxjs?
我知道有很多关于标题主题的问题,但我无法找到有助于我跟进的清晰简洁的问题/回复。
假设我们有 x 数量的 web api 调用返回 observables Observable<cs[]>... 见
init() {
this.service.serviceA().subscribe({
next: (as) => {
this.as = as;
this.service.serviceB().subscribe({
next: (bs) => {
this.bs = bs;
this.service.serviceC().subscribe({
next: (cs) => {
this.cs = cs;
this.restructureABCs();
},
error: (e) => this.notification.showError('Failed to load cs! Error: ' + e.messageerror)
});
},
error: (e) => this.notification.showError('Failed to load bs! Error: ' + e.messageerror)
});
},
error: (e) => this.notification.showError('Failed to load as! Error: ' + e.messageerror)
})
}
Function restructureABCs()取决于 as/bs & cs。 因为,bs & cs 不相互依赖。 当前的实现很丑陋,可以改进,但我不确定应该使用哪个运算符。 使用 concatMap 对我来说没有意义,因为(根据我可能有缺陷的理解)多个流将被合并为一个,这是我不想要的。 我只需要确保在调用restructureABCs() function 之前加载 as/bs & cs。
Angular13,rxjs7.4
如果 BS、CS、AS 不相互依赖,它们可以并行运行,您只需要确保所有这些 Observable 都完成以运行 restructureABCs()。 因此,您可以在这种情况下使用 combineLatest/forkJoin。
combineLatest([
this.service.serviceA().pipe(catchError(er => ...)),
this.service.serviceB().pipe(catchError(er => ...)),
this.service.serviceC().pipe(catchError(er => ...))
]).subscribe(response => {
this.as = response[0];
this.bs = response[1];
this.cs = response[2];
restructureABCs()
})
这是我使用forkJoin提出的解决方案。
as : Array<as>;
bs : Array<bs>;
cs : Array<cs>;
as$: Observable<as[]> = this.service.serviceA();
bs$: Observable<bs[]> = this.service.serviceB();
cs$: Observable<cs[]> = this.service.serviceC();
init() {
forkJoin([
this.as$.pipe(catchError(er => of({errMsg: 'Failed to load as! Error: ', error: er}))),
this.bs$.pipe(catchError(er => of({errMsg: 'Failed to load bs! Error: ', error: er}))),
this.cs$.pipe(catchError(er => of({errMsg: 'Failed to load cs! Error: ', error: er})))
])
.subscribe({
next: ([a, b, c]) => {
this.as = a as Array<as>;
this.bs = b as Array<bs>;
this.cs = c as Array<cs>;
this.restructureABCs();
},
error: (e) => this.notification.showError(e.errMsg)
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.