如果已经使用相同的请求运行,则取消订阅/取消 Angular 4 中的现有 HTTP/XHR 调用

Posted

技术标签:

【中文标题】如果已经使用相同的请求运行,则取消订阅/取消 Angular 4 中的现有 HTTP/XHR 调用【英文标题】:Unsubscribe/Cancel the existing HTTP/XHR calls in angular 4 if already running with same request 【发布时间】:2019-02-07 08:31:30 【问题描述】:

问题陈述:目前我有一个前端应用程序,它在一个页面中有 5 个图表(每个图表都有一个不同的端点来获取数据)根据从数据库中检索到的数据进行渲染,并且我有一个更新的下拉列表基于从下拉列表中选择的值的图表。

现在在前端,图表将加载默认值,我的要求是,每当用户选择任何下拉菜单并且如果有任何 HTTP 调用(来自默认值)运行时,我想取消它们并发出新请求(主要原因因为有时来自上一个请求的数据比从下拉列表中选择的最新数据花费的时间更长,因此我的图表仍然使用旧请求而不是从下拉列表中选择的新值更新,正如我从 Chrome 网络选项卡中看到的那样,旧请求在最新请求之后完成,因此使用旧请求更新图)并且所有这些图都向这些方法发出并行请求以呈现数据。

在@Amit Chigadani 的帮助下,我目前在服务中编写了以下函数,但是使用这种方法,即使是来自最新请求的端点也会被取消并且根本不会呈现图表,你能不能帮我解决方法

在服务中

getData(url: string) 
    const finalRequest = new RequestModel(this.myModel);
    const body = JSON.stringify(finalRequest);
    const headers = new Headers( "Content-Type": "application/json" );
    const options = new RequestOptions( headers: headers );

    return this.http.post(url, body, options).switchMap((res) => 
        const resp = res.json();
        return Observable.of(resp);
    );

在组件中

public mySub: Subscription;

if (this.mySub !== undefined) 

    this.mySub.unsubscribe();


this.mySub = this.myService.getData(this.url).subscribe((data) => 
    try 
    
    catch (err) //do something if error
    
    return this.mySub;
);

版本

角度:4.0.1 rxjs : 5.0.3

【问题讨论】:

您在此处显示的组件代码是包含所有这 5 个子组件的父组件吗?如果这是真的,我正在做一个新的答案 为什么要取消订阅 mySub ? SwitchMap 应该取消之前的,并且已经接受了最新的 http 请求。 【参考方案1】:

好吧,忘记switchMap,这里没用。

来自聊天:

我理解这个问题主要是因为我有不同的 并行调用此方法的子组件,我有 所有图表的相同订阅,因此任何时候都有新请求 它取消订阅请求..有没有办法解决这个问题 出去

我看到您为每个 http 请求调用了相同的方法。我的猜测是,每当child 之一发出下拉值更改event 时,您就会在parent component 中执行此操作。

编辑

从聊天中可以清楚地看出,OP 实际上是指 parent-child 组件,就 inheritance 而言,而不是 angular 上下文。

Child1, Child2... 类是从Parent 扩展而来的

因此,这些Child 组件中的每一个现在都将有一个单独的mySub 订阅对象实例,可以并行订阅。并且来自子组件之一的先前请求的unsubscribing 不应来自其他child 组件的unsubscribe 实例。

只有当同一个组件说Child1 触发第二个http 请求时,它自己之前的subscription 才会被杀死,而新的subscription 会在child1 实例上创建。

查看此demo 以检查instances 未在child 组件之间共享。它们都是独立的。

【讨论】:

注意:我假设 OP 使用的是angular2。因此,我添加了这个答案。 嗨,Amit 感谢您的回答,特别是我使用的是 Angular 4,但是当我使用 switchMap 时,我收到一个错误,You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. 如果你想在服务中执行任何逻辑,那么你仍然可以只在switchMap内部进行。在这种情况下,您可以创建一个块,然后从switchMap 创建return。检查更新的答案。 谢谢阿米特,但我仍然面临同样的问题,当调用这是我的组件上的一个方法时,它显示空对象而不是数据的数据类型:any image1 image2 它没有显示空对象。错误表示您无法从该对象获取属性 filter。因为它不知道那个对象的类型。您可以将其类型声明为anysubscribe((data : any) => ... 还有console.log(data) 在组件内部打印什么。收到回复了吗?

以上是关于如果已经使用相同的请求运行,则取消订阅/取消 Angular 4 中的现有 HTTP/XHR 调用的主要内容,如果未能解决你的问题,请参考以下文章

如何查看和修改请求订阅属性 (SQL Server Management Studio)

没有 ngOnDestroy,角度取消订阅不起作用

PHP cURL取消订阅PayPal问题

取消 iOS 订阅

如何在 Angular 4+ 中取消/取消订阅所有挂起的 HTTP 请求

React Apollo - 取消订阅查询