Angular 2使用observable的功能缓存http请求
我发现了许多缓存反应式可观察量的方法,更具体地说,是http请求的结果.但是,由于以下原因,我对提议的解决方案并不完全满意:
1.此答案https://stackoverflow.com/a/36417240/1063354使用私有字段存储第一个请求的结果,并在所有后续调用中重用它. 代码: private data: Data; getData() { if(this.data) { return Observable.of(this.data); } else { ... } } 可悲的是,可观察力的力量完全被忽略了 – 你手动完成所有的东西.事实上,如果我对将结果分配给局部变量/字段感到满意,我就不会寻找合适的解决方案. 2.这个答案https://stackoverflow.com/a/36413003/1063354建议使用ReplaySubject: private dataObs$= new ReplaySubject(1); constructor(private http: Http) { } getData(forceRefresh?: boolean) { // If the Subject was NOT subscribed before OR if forceRefresh is requested 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); // Recreate the Observable as after Error we cannot emit data anymore this.dataObs$= new ReplaySubject(1); } ); } return this.dataObs$; } 看起来非常棒(再次 – 清除缓存没有问题)但我无法映射此调用的结果,即 service.getData().map(data => anotherService.processData(data)) 这是因为底层观察者没有调用其完整方法.我很确定很多反应方法也不适用于此.要实际获取数据,我必须订阅此observable,但我不想这样做:我想通过解析器获取我的一个组件的缓存数据,该解析器应该返回一个Observable(或Promise),而不是订阅: 路线 { path: 'some-path',component: SomeComponent,resolve: { defaultData: DefaultDataResolver } } 解析器 ... resolve(route: ActivatedRouteSnapshot,state: RouterStateSnapshot): Observable<Data> { return this.service.getData(); } 永远不会激活组件,因为它的依赖性永远不会被解析. 3.在这里https://stackoverflow.com/a/36296015/1063354我找到了一个使用publishLast().refCount()的提议. 代码: getCustomer() { return this.http.get('/someUrl') .map(res => res.json()).publishLast().refCount(); } 这满足了我对缓存和解析的要求但是我还没有找到一个干净整洁的解决方案来清除缓存. 我错过了什么吗?任何人都可以想出一种更好的方法来缓存反应性可观察量能够映射其结果,以及一旦它不再相关就刷新缓存数据吗? 解决方法
这个简单的类缓存结果,因此您可以多次订阅.value并只发出1个请求.您还可以使用.reload()发出新请求并发布数据.
您可以像以下一样使用它: let res = new RestResource(() => this.http.get('inline.bundleo.js')); res.status.subscribe((loading)=>{ console.log('STATUS=',loading); }); res.value.subscribe((value) => { console.log('VALUE=',value); }); 和来源: export class RestResource { static readonly LOADING: string = 'RestResource_Loading'; static readonly ERROR: string = 'RestResource_Error'; static readonly IDLE: string = 'RestResource_Idle'; public value: Observable<any>; public status: Observable<string>; private loadStatus: Observer<any>; private reloader: Observable<any>; private reloadTrigger: Observer<any>; constructor(requestObservableFn: () => Observable<any>) { this.status = Observable.create((o) => { this.loadStatus = o; }); this.reloader = Observable.create((o: Observer<any>) => { this.reloadTrigger = o; }); this.value = this.reloader.startWith(null).switchMap(() => { if (this.loadStatus) { this.loadStatus.next(RestResource.LOADING); } return requestObservableFn() .map((res) => { if (this.loadStatus) { this.loadStatus.next(RestResource.IDLE); } return res; }).catch((err)=>{ if (this.loadStatus) { this.loadStatus.next(RestResource.ERROR); } return Observable.of(null); }); }).publishReplay(1).refCount(); } reload() { this.reloadTrigger.next(null); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- linux 下安装redis以及php Redis扩展
- virtualBox 虚拟机下nginx设置不缓存静态文件不起作用解决办
- 如何设置-e选项时如何避免bash脚本失败?
- angularjs – 推送或取消进入$http(非全局)的transformRequ
- 如何使用angularjs在c#中调用API
- 欺骗循环/ autorefresh docker ps视图,如bash中的top/htop
- 【转】angularJS的兄弟controller之间如何正确的通信
- Scala Play Framework – 控制器作为类或单例
- Bootstrap(1)基础概念
- Couldn't register com.yourcompany.XXX with bootstra