【发布时间】:2019-02-08 16:44:48
【问题描述】:
更改页面时取消挂起的 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() 期间调用的服务中创建一个拆卸方法,但除非我完成了流,否则它不起作用。但那时,当用户返回页面时,我无法再次重新启动流。
tearDown(): void {
this.unsubscribe$.next();
this.unsubscribe$.complete();
// this.dataSubject.next(null);
// this.dataSubject.complete(); -- breaks
}
我绝不是 RXJS 专家,如果我的整体设计有误,请随时指出。我怀疑我应该使用 switchMap() 或 share 来防止两个消费者发出相同的请求;但由于这种可观察到的模式是半热的,我不确定正确的做法是什么。更不用说取消它了。
我们将不胜感激。
【问题讨论】:
-
是的,所以既然你有behaviorSubject,你应该实际使用它。您应该使用 this.dataSubject.next(apiData) 将返回的数据推送到 behaviorSubject 中,而不是返回 this.data$。然后 3 个消费者订阅公共 data$,假设他们都订阅了,当在 getData() 方法中触发 dataSubject.next() 时,它们将被更新。让我知道这是否没有意义。本质上,这变成了一个 rxjs 数据存储,将其视为一个轻量级的状态,沿着 redux/ngrx 的路线,没有动作、reducers、连接器等的所有开销
-
@Budhead2004 我还没有用 this.dataSubject.next(availableDevices); ?
标签: angular http rxjs observable rxjs-pipeable-operators