Angular2 可观察共享不起作用

Angular2 observable share is not working

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 调用吗?

您正在为此处的每个 .getData() 调用创建一个新流:

this.buildings$ = this.http.get('http://localhost:8080/buildings').share().map(this.extractData);

如果你想 "share" 组件之间的数据并防止多次 rest-calls,你很可能必须使用 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) 将向未来的订阅者重新发送("replay")最后发送的数据,因此不会进行新的调用。

我认为这只是对 share() 的误解。

当您调用 this.buildings$.subscribe(...) 时,由于 share() 运算符,它会生成 ConnectableObservable,紧接着是 connect()

如果您在 HTTP 请求挂起时进行另一个订阅,它只会将另一个观察者添加到 ConnectableObservable,当响应准备好时,它将发送给两个观察者。但是,如果您让 this.buildings$ 完成并在之后再次订阅,它将发出另一个 HTTP 请求,因为 ConnectableObservable 未连接到其源。

你想要的是 .publishReplay(1).refCount()(或自 RxJS 5.4.0 起的 shareReplay(1))重播从源发出的最后一个项目。您很可能还想附加 take(1) 以正确完成链。

您正在订阅服务和组件中的可观察对象。试试这个作为您服务中的 getData 方法:

getData() : Observable<Building[]>{
 return this.http.get('http://localhost:8080/buildings')
    .map(this.extractData);
}