Angular2 Observable共享无效并且重复http调用
BuildingService.ts
@Injectable()
export class BuildingService {
constructor(private http: Http){
}
buildings$: Observable<Building[]>;
this.buildings: Building[];
getData() : Observable<Building[]>{
this.buildings$ = this.http.get('http://localhost:8080/buildings').share().map(this.extractData);
this.buildings$.subscribe(buildings => this.buildings = buildings);
return this.buildings$;
}
private extractData(res: Response) {
let body = res.json();
return body;
}
}
component1.ts
export class component1 {
constructor( private buildingService: BuildingService) {}
this.subscription = this.buildingService.getData()
.subscribe(buildings => console.log(buildings),
error => this.errorMessage = <any>error);
}
component2.ts
export class component2 {
constructor( private buildingService: BuildingService) {}
this.subscription = this.buildingService.getData()
.subscribe(buildings => console.log(buildings),
error => this.errorMessage = <any>error);
}
共享无效,多个http调用正在进行中。我甚至尝试过this link
的代码但没有用。
有人可以告诉我如何使用Angular Observable避免重复的http调用吗?
答案 0 :(得分:10)
我认为这只是对share()
所做的误解。
当您致电this.buildings$.subscribe(...)
时,ConnectableObservable
感谢share()
运营商,紧随其后的是connect()
。
如果您在HTTP请求处于待处理状态时再次订阅,则只会向ConnectableObservable
添加另一个Observer,并且当响应准备就绪时,它将被发送给两个观察者。但是,如果您让this.buildings$
完成,之后再次订阅它会发出另一个HTTP请求,因为ConnectableObservable
未连接到其来源。
您想要的是.publishReplay(1).refCount()
(或自{RxJS 5.4.0以来的shareReplay(1)
)重放从源发出的最后一项。您很可能还希望附加take(1)
来正确完成链。
答案 1 :(得分:2)
您正在使用.getData()
创建一个新流 - 请在此处调用:
this.buildings$ = this.http.get('http://localhost:8080/buildings').share().map(this.extractData);
如果你想&#34;分享&#34;组件之间的数据和防止多次休息调用,你必须最有可能使用rxjs的重放功能,例如你可以做这样的事情:
@Injectable()
export class BuildingService {
constructor(private http: Http){}
buildings$: Observable<Building[]>;
this.buildings: Building[];
getData(fetchNew: boolean = false) : Observable<Building[]>{
if (fetchNew || !this.buildings$) {
this.buildings$ = this.http.get('http://localhost:8080/buildings')
.map(this.extractData)
.publishReplay(1)
.refCount();
this.buildings$.subscribe(buildings => this.buildings = buildings);
}
return this.buildings$;
}
private extractData(res: Response) {
let body = res.json();
return body;
}
}
publishReplay(1)
将重新发出(&#34;重播&#34;)最后发送的数据给未来的订阅者,因此不会进行新的通话。
答案 2 :(得分:-2)
您在服务和组件中订阅了observable。尝试将此作为服务中的getData方法:
getData() : Observable<Building[]>{
return this.http.get('http://localhost:8080/buildings')
.map(this.extractData);
}