I found several approaches for caching reactive observables and, more specifically, the results of HTTP requests. However, I am not completely satisfied with the proposed solutions for the following reasons:
1. This answer, https://stackoverflow.com/a/166268/2126, uses a private field to store the result of the first request and reuse it in all subsequent calls.
the code:
private data: Data;
getData() {
if(this.data) {
return Observable.of(this.data);
} else {
...
}
}
The sad thing is that the power of the observables is completely ignored - you do it all manually. Actually, I would not be looking for the right solution if I were satisfied with assigning the result to a local variable / field. Another important thing that I consider bad practice is that the service should not have a state - that is, there should not be private fields containing data that change from call to call. And it's pretty easy to clear the cache - just set this.data to null and the request will be re-executed.
2. This answer, https://stackoverflow.com/a/3126268/2166, suggests using ReplaySubject:
private dataObs$ = new ReplaySubject(1);
constructor(private http: Http) { }
getData(forceRefresh?: boolean) {
if (!this.dataObs$.observers.length || forceRefresh) {
this.http.get('http://jsonplaceholder.typicode.com/posts/2').subscribe(
data => this.dataObs$.next(data),
error => {
this.dataObs$.error(error);
this.dataObs$ = new ReplaySubject(1);
}
);
}
return this.dataObs$;
}
It looks pretty amazing (and again - there is no problem with clearing the cache ), but I cannot match the result of this call, i.e.
service.getData().map(data => anotherService.processData(data))
, . , . , , : resolver, ( Promise), :
{
path: 'some-path',
component: SomeComponent,
resolve: {
defaultData: DefaultDataResolver
}
}
...
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Data> {
return this.service.getData();
}
, .
3. qaru.site/questions/39248/... publishLast(). refCount().
:
getCustomer() {
return this.http.get('/someUrl')
.map(res => res.json()).publishLast().refCount();
}
, .
- ? - , , , ?