Cancel flatMap observable call chain

懵懂的女人 提交于 2019-12-12 12:05:00

问题


I am using angular 5 and rxjs. I am making 2 service calls, one dependent on others results. I am doing it using flatMap. I am also using takeUntil so that I can abort operation at any given point. My code looks like below:

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
})

This code is executed in for loop and loop gets executed for 200 times. Therefore 400 network calls are made. I have a button on UI to abort this operation and this.destroyed$ observable gets executed when it is clicked. I can abort this way for any iteration where second API call is not made(api2). If only first API is getting called, that request gets cancelled. If api2 has been called, which takes 20-30 seconds to respond, it doesn't get cancelled. I want both API calls to be cancelled. Is it possible?


回答1:


You can just restructure your chain and put takeUntil at the end.

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
});

The problem you had is in how mergeMap works internally (this is on purpose). mergeMap merges its source Observable and all inner Observables. So if you put takeUntil before mergeMap you're just completing the source Observable while all inner Observables are still active.

If you put it after mergeMap it will make the observer to complete which triggers dispose handlers bottom-up order and when mergeMap is unsubscribed it unsubscribes from its inner Observables.

This is the relevant line: https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/mergeMap.ts#L147

Also have a look at this article from one of RxJS Core Devs: https://blog.angularindepth.com/rxjs-avoiding-takeuntil-leaks-fb5182d047ef



来源:https://stackoverflow.com/questions/54783869/cancel-flatmap-observable-call-chain

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!