如何通过RXJS在内部HTTP中取消待处理的请求?

时间:2019-02-08 16:44:49

标签: angular http rxjs observable rxjs-pipeable-operators

更改页面时取消待处理的HTTP请求

我们有一个Angular服务,它具有昂贵的HTTP查询,三个不同的使用者都可以访问。每个使用者都可以在任何时候修改此查询,发出新请求,并且所有其他使用者都必须使用新数据进行更新。

由于HTTP订阅在完成后立即关闭,因此我们将内部可观察模式与行为主体一起使用,以使使用者保持联系(见下文)。

然后的问题是,当用户更改页面时,无法取消当前的挂起的HTTP响应。

通常,我认为在后台丢弃HTTP请求不会有太大的问题...但是除了这是一个昂贵的操作之外,我发现在用户之后是否确实解决了挂起的响应已返回页面,它将使用较旧查询的数据更新使用者。

没有布宜诺斯艾利斯。

服务电话

private dataSubject = new BehaviorSubject<MyData>(...);
public data$ = this.dataSubject.asObservable();
...

getData(): Observable<MyData> {
  if (this.dataSubject)
    return this.data$;
  } else {
    const http$ = this.http.post(...))
      .pipe(map(response => response as MyData),
        takeUntil(this.unsubscribe$)); // see tearDown() below
    http$.subscribe(
      (availableDevices: MyData) => {
        this.dataSubject.next(availableDevices);
      }
    );
    return this.data$;
  }
}

我试图在每个使用者在ngDestroy()期间调用的服务中创建一个拆卸方法,但是除非完成流,否则该方法无效。但是到那时,当用户返回页面时,我不再无法重新启动流。

tearDown(): void {
  this.unsubscribe$.next();
  this.unsubscribe$.complete();
  // this.dataSubject.next(null);
  // this.dataSubject.complete(); -- breaks
}

我绝不是RXJS专家,所以请指出我的总体设计是否错误。我有点怀疑我应该使用 switchMap() share 来防止两个消费者发出相同的请求;但是由于这种可观察的模式是半热的,所以我不确定正确的做法是什么。取消它就更不用说了。

任何人和所有帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

我解决了将Promises(异步函数)与AbortSignal / AbortController一起使用的问题,因为在我的情况下,尽管取消了主题,但http请求并未被取消。也许我犯了一个错误,或者现在可以正常工作。但是,使用AbortController的Promise也可以完成这项工作。

请参见here,如何使用AbortController。但是,使用AbortController时,浏览器兼容性可能会出现问题。

您还可以使用.toPromise()将可观察对象转换为Promise,这样就不会成为问题。

答案 1 :(得分:1)

取消http呼叫的最简单方法是取消订阅。

const subscription: Subscription = this.http.post(...).subscribe(...);
subscription.unsubscribe();

您的teardown方法很有用,通常用作垃圾回收并取消任何待处理的rxjs可观察对象。您可以在service / component / directive ngOnDestroy挂钩中调用它,以确保内存中没有可观察到的物体。

但是,如果我没记错的话,角度处理http可观察对象,因此您不需要处理它们。通常来说,您只需要照顾自己产生的可观察物,例如BehaviorSubject