我正在使用angular 5和rxjs。我正在拨打2个服务电话,其中一个取决于其他结果。我正在使用flatMap。我也在使用takeUntil,以便可以在任何给定点中止操作。我的代码如下所示:
this.myservice.api1(param1).pipe(takeUntil(this.destroyed$), finalize(() => {
//do something after both api calls are completed
},
flatMap((result1) => {
//do some operation and create object x(this.objx)
return this.myservice.api2(param1);
})
).subscribe((result2) => {
//do something based on result2 and this.objx
})
此代码在for循环中执行,循环执行200次。因此,进行了400个网络呼叫。我在UI上有一个按钮来中止此操作,并且单击它时将执行 this.destroyed $ 可观察的对象。对于未进行第二次API调用的任何迭代,我都可以中止这种方式(api2)。如果只调用第一个API,该请求将被取消。如果api2被调用,需要20到30秒的响应时间,它不会被取消。我希望两个API调用都被取消。有可能吗?
答案 0 :(得分:4)
您只需重组链,然后将takeUntil
放在最后。
this.myservice.api1(param1).pipe(
mergeMap((result1) => { // flatMap is just alias for `mergeMap` which is the recommended name you should use
//do some operation and create object x(this.objx)
return this.myservice.api2(param1);
}),
takeUntil(this.destroyed$),
finalize(() => {
//do something after both api calls are completed
},
).subscribe((result2) => {
//do something based on result2 and this.objx
});
您遇到的问题是mergeMap
在内部的工作方式(这是有目的的)。 mergeMap
合并其源Observable和所有内部Observable。因此,如果将takeUntil
放在mergeMap
之前,则只是在所有内部Observable仍处于活动状态时完成源Observable。
如果将其放在mergeMap
之后,它将使观察者完成触发触发器处理程序自下而上的顺序,并且当mergeMap
取消订阅时,它将取消其内部Observable的订阅。
这是相关行:https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/mergeMap.ts#L147
也可以从RxJS Core Devs之一中查看此文章:https://blog.angularindepth.com/rxjs-avoiding-takeuntil-leaks-fb5182d047ef