更改页面时取消待处理的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 来防止两个消费者发出相同的请求;但是由于这种可观察的模式是半热的,所以我不确定正确的做法是什么。取消它就更不用说了。
任何人和所有帮助将不胜感激。
答案 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
。