我为我的一个项目使用角度4,我正在进行http调用以获取数据。我从后端返回数据时缓存数据,这样对于后续请求,我就不必一次又一次地进行其余的调用。
getApplication(): Observable<Array<Application>> {
return new Observable<Array<Application>>((observer) => {
if (this.app&& this.app.length > 0) {
observer.next(this.app)
} else {
this._http
.get<Application[]>(this.url)
.map((app) => this.mapToApp(app))
.subscribe((result: Array<Application>) => {
observer.next(result);
}, () => {
observer.next([]);
})
}
})
}
这完全没问题。但是,如果两个呼叫同时进行,我看到网络选项卡中有两个请求而不是一个。所以我尝试使用share()来满足'一个可观察的,多个订户'。
getApplication(): Observable<Array<Application>> {
return new Observable<Array<Application>>((observer) => {
if (this.app&& this.app.length > 0) {
observer.next(this.app)
} else {
this._http
.get<Application[]>(this.url)
.map((app) => this.mapToApp(app))
.subscribe((result: Array<Application>) => {
observer.next(result);
}, () => {
observer.next([]);
})
}
}).share()
}
但是,我也看到网络标签中有多个请求而不是一个。只需拨打一个电话并与所有订户共享结果需要做些什么?请帮忙。
答案 0 :(得分:2)
我的第一个建议是考虑在这些行中的代码中进行一些简化
getApplication(): Observable<Array<Application>> {
if (this.app && this.app.length > 0) {
return Observable.of(this.app);
}
return this._http
.get<Application[]>(this.url)
.map((app) => this.mapToApp(app))
.do((result: Array<Application>) => {
this.app = result;
}
}
使用此逻辑,您可以使用所需的任何逻辑进行缓存。您已决定检查this.app
是否为空,以及是否包含某些元素。但是你可以使用任何其他逻辑,可能取决于输入参数。
另一个故事是同时发出2个电话的问题。在这种情况下,您可能希望两者都share
Observable,以便只共享一个订阅并记录最后一个结果replay
,以便您可以返回缓存的值。
执行此操作的一种方法可能是以下
private cache$: Observable<Array<Application>>;
requestApplication(): Observable<Array<Application>> {
return this._http
.get<Application[]>(this.url)
.map((app) => this.mapToApp(app))
.do((result: Array<Application>) => {
this.app = result;
}
}
getApplication() {
if(!cache$) {
cache$ = this.requestApplication().shareReplay(1);
}
return cache$;
}
此处的技巧由shareReplay
运算符执行。 share 部分确保共享订阅。缓冲区大小为1的重放部分确保始终返回存储的最后结果。
然后您可能会遇到偶尔清除缓存的问题。但是这里的故事变得更加复杂,我建议你看看这篇非常好的文章https://blog.thoughtram.io/angular/2018/03/05/advanced-caching-with-rxjs.html
答案 1 :(得分:0)
你是否两次调用getApplication()方法?如果是,那么您创建两个不同的可观察量。
也许您应该使用主题来关注发布者/订阅者模式?