取消flatMap可观察的呼叫链

时间:2019-02-20 10:17:20

标签: angular rxjs

我正在使用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调用都被取消。有可能吗?

1 个答案:

答案 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