取消flatMap可观察的呼叫链 [英] Cancel flatMap observable call chain

查看:66
本文介绍了取消flatMap可观察的呼叫链的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用angular 5和rxjs.我正在拨打2个服务电话,其中一个取决于其他结果.我正在使用flatMap做到这一点.我也在使用takeUntil,以便可以在任何给定点中止操作.我的代码如下所示:

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

此代码在for循环中执行,循环执行200次.因此,进行了400次网络呼叫.我在UI上有一个按钮来中止此操作,并且单击它时将执行 this.destroyed $ 可观察的对象.对于没有进行第二次API调用的任何迭代,我可以中止这种方式(api2).如果仅调用第一个API,该请求将被取消.如果api2已被调用,需要20到30秒的响应时间,则不会被取消.我希望两个API调用都被取消.有可能吗?

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?

推荐答案

您只需重组链并将takeUntil放在末尾即可.

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

您遇到的问题是mergeMap在内部的工作方式(这是有目的的). mergeMap合并其源Observable和所有内部Observable.因此,如果将takeUntil放在mergeMap之前,则只是在所有内部Observable仍处于活动状态时完成源Observable.

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.

如果将其放在mergeMap之后,它将使观察者完成触发触发器处理程序自下而上的顺序,并且当mergeMap取消订阅时,它将取消其内部Observable的订阅.

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.

这是相关行: https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/mergeMap.ts#L147

也可以从RxJS核心开发人员之一查看这篇文章: https://blog.angularindepth.com/rxjs-avoiding-takeuntil-leaks-fb5182d047ef

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

这篇关于取消flatMap可观察的呼叫链的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆