如何使用 RXJS 取消可观察到的内部 HTTP 中的待处理请求?

How to cancel a pending request in an inner HTTP observable with RXJS?

更改页面时取消挂起的 HTTP 请求

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

由于 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() 期间调用的服务中创建一个拆卸方法,但除非我完成流,否则它不起作用。但那时,当用户 returns 到页面时,我无法再次重新启动流。

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

我绝不是 RXJS 专家,如果我的整体设计有误,请随时指出。我一直怀疑我应该使用 switchMap()share 来防止两个消费者发出相同的请求;但是因为这种可观察到的模式是半热的,所以我不确定正确的做法是什么。更不用说取消了。

任何帮助都将不胜感激。

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

参见 here 如何使用 AbortController。但是,使用AbortController时可能存在浏览器兼容性问题。

您还可以使用 .toPromise() 将 observables 转换为 promise,这样这应该不是问题。

取消 http 调用的最简单方法是取消订阅。

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

您的 teardown 方法很有用,通常用作垃圾收集和取消任何挂起的 rxjs observables。您可以在 service/component/directive ngOnDestroy 挂钩中调用它,以确保没有可观察对象保留在内存中。

但如果我没记错的话,angular 处理 http observables,所以你不需要处理它们。一般来说,您只需要处理自己生成的可观察对象,例如您的 BehaviorSubject.