您可以构建简单的类 可缓存
declare type GetDataHandler<T> = () => Observable<T>;
export class Cacheable<T> {
protected data: T;
protected subjectData: Subject<T>;
protected observableData: Observable<T>;
public getHandler: GetDataHandler<T>;
constructor() {
this.subjectData = new ReplaySubject(1);
this.observableData = this.subjectData.asObservable();
}
public getData(): Observable<T> {
if (!this.getHandler) {
throw new Error("getHandler is not defined");
}
if (!this.data) {
this.getHandler().map((r: T) => {
this.data = r;
return r;
}).subscribe(
result => this.subjectData.next(result),
err => this.subjectData.error(err)
);
}
return this.observableData;
}
public resetCache(): void {
this.data = null;
}
public refresh(): void {
this.resetCache();
this.getData();
}
}
用法
声明可缓存
list: Cacheable<string> = new Cacheable<string>();
和处理程序:
this.list.getHandler = () => {
// get data from server
return this.http.get(url)
.map((r: Response) => r.json() as string[]);
}
来自组件的调用:
//gets data from server
List.getData().subscribe(…)
更多细节和代码示例如下:http://devinstance.net/articles/20171021/rxjs-cacheable
我认为您不应该在构造函数中或angular生命周期中的任何时候执行fetch()。正如您所说,ngOnInit
在角度服务中不起作用。
相反,我们希望利用 rxjs 通过流无缝地传递缓存值 - 而调用方不必了解缓存值与非缓存值的任何信息。
如果一个组件需要一个数据,它就订阅它,不管它是否被缓存。为什么要获取()一个你不确定会被使用的数据呢?
缓存应该在更高的层次上实现,我认为这种实现是一个好的开始:http://www.syntaxsuccess.com/viewarticle/caching-with-rxjs-observables-in-angular-2.0
getFriends(){
if(!this._friends){
this._friends = this._http.get('./components/rxjs-caching/friends.json')
.map((res:Response) => res.json().friends)
.publishReplay(1)
.refCount();
}
return this._friends;
}
我不确定这是不是最好的方法,但是它更容易维护,因为它只有一个责任。只有当一个组件订阅数据时,数据才会被缓存,不管是什么/谁/哪个组件需要数据并且是第一个需要它的。
如果您倾向于将observables作为一种共享数据的方式,您可以采用以下方法:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, ReplaySubject } from 'rxjs';
import { SomeModel } from 'path/to/it';
@Injectable({
providedIn: 'root'
})
export class CachedService {
private dataSubject = new ReplaySubject<SomeModel>(1);
data$: Observable<SomeModel> = this.dataSubject.asObservable();
constructor(private http: HttpClient) { }
fetch() {
this.http.get<SomeModel>(...).subscribe(res => this.dataSubject.next(res));
}
}
这将在调用 fetch
方法时进行 HTTP 调用,并且 service.data$
的任何订阅者都将从 ReplaySubject
获得响应。当它重播早期值时,在 HTTP 调用解析后加入的任何订阅者仍将获得以前的响应。
如果您想触发更新,您可以调用service.fetch()
来启动新的HTTP调用,一旦新响应到达,所有订阅者都将被更新。
您的组件看起来会像这样:
@Component({ ... })
export class SomeComponent implements OnDestroy, OnInit {
private subscription?: Subscription;
constructor(private service: CachedService) { }
ngOnInit() {
this.service.fetch();
this.subscription = this.service.data$.subscribe(...);
}
ngOnDestroy() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
}
我最近为我的同事写了一篇关于这种方法的博客文章:http://blog.jonrshar.pe/2017/Apr/09/async-angular-data.html
我试图禁用我的AngularJS应用程序中的缓存,但它无法使用以下代码: 当我使用
我只是有一个关于服务中http请求的结构和处理响应的问题。我正在使用Angular2。alpha46 Typescript(刚刚开始测试-我喜欢它…Ps…。感谢所有一直致力于它并通过github作出贡献的人) 因此,采取以下措施: 登录表单。组成部分ts 从这个组件中,我导入了我的userService,它将容纳我的超文本传输协议请求,以登录用户。 使用者服务ts 我想做的是能够处理http请求之
我所做的: 我正在使用vertx rx超文本传输协议客户端来执行大量的HTTP请求。在这种情况下,我调用“方法A”,它返回一个ID列表。要接收所有ID,我需要多次调用方法A以获取下一批结果。(每次我指定一个不同的页码我想接收) 为了提高性能并尽可能并行地进行调用,我创建了一个(RxJava)可观察项目列表,每个项目代表单个页面请求的结果。当我完成创建此列表时,我调用Obserable.zip运算符
我有一个由Python构建的API服务器。我需要一组客户端/计算机通过发出http post请求将数据发送到API服务器。 这里的数据实际上是html内容。(注意:我没有将合法数据转换为HTML/XML格式,数据本身就是我从web上收集的HTML),通常每页约200KB。我正试图通过使用串行/串行和压缩来尽可能减轻网络负载。 我正在考虑通过网络发送原始超文本标记语言。有没有类似序列化html对象的
我以前问过这个问题,但没有得到答案。我可以使用下面的方法:“get”让它工作,所以这没关系,但这次我需要使用post。在另一个项目中(使用react、redux、php、webpack、xampp),同样的问题再次出现,我正在努力解决它。这就是: register.php index.js 当我做了以上的一切是好的,数据是日志作为'做某事'。但是,当我尝试使用axios({方法:'POST'})并
我正在使用GWT和Spring controller来管理http流量。有些请求可能需要很长时间,但我希望在超过给定时间时终止请求。 我如何配置超时Spring。我也使用Apache Tomcat 7.0。我试图在tomcat上inrease最大线程,但有一段时间tomcat工作缓慢,因为请求线程不会死。