简体   繁体   English

Angular Observable被多次调用

[英]Angular Observable being called multiple times

I have a service in which I defined a global observable like so: 我有一个服务,其中定义了一个全局可观察对象,如下所示:

 @Injectable()
  export class XYZService {
    country: Observable<any>;
    isBrowser: boolean;

    constructor(private http: Http,
                private httpClient: HttpClient,
                private router: Router,
                @Inject(PLATFORM_ID) private platformId: any) {
      this.isBrowser = isPlatformBrowser(platformId);
      if(this.isBrowser && !this.country) {
      this.country = this.http.get('https://ipinfo.io')
        .map(res => res.json())
        .catch(() => {
          return Observable.of({'country': 'SG'});
        }); 
      };
    }

    getLocation(): Observable<any> {
      return this.country;
    }

Now in several of my components I'm calling the getLocation function in the constructor or ngOnInit like so: 现在在我的几个组件中,我像这样在构造函数或ngOnInit中调用getLocation函数:

this.XYZService.getLocation()
  .subscribe(res => {
    this.country = res['country'];
});

My expectation is that the request to ipinfo.io would only be made once. 我的期望是对ipinfo.io的请求只会被发送一次。 However that is not happening. 但是,这没有发生。 From the network logs I can see that the request to ipinfo is being made multiple times. 从网络日志中,我可以看到多次向ipinfo发出请求。 Looks to be some timing issue. 看起来是一些计时问题。 If I add a debugger or console.log statement within the constructor, it is only called once. 如果在构造函数中添加调试器或console.log语句,则仅调用一次。 However more than one request are sent. 但是,发送了多个请求。

You can use the rxjs share operator. 您可以使用rxjs 共享运算符。 This will ensure that subsequent subscribers will share the same observable sequence (until the number of observers returns to 0) 这将确保后续的订户共享相同的可观察序列(直到观察者的数量返回0为止)

this.country = this.http.get('https://ipinfo.io')
    .map(res => res.json())
    .catch(() => {
      return Observable.of({'country': 'SG'});
    })
    .share();

You can also use the shareReplay operator. 您也可以使用shareReplay运算符。 The difference is the observable result will be stored for any subscribers in the future. 不同之处在于,将来将为所有订户存储可观察的结果。 For example say you subscribe to the observable when the app loads, with shareReplay when you subscribe 10+ minutes later, the observable will return the same result and not make another http request. 例如,说您在应用程序加载时订阅了可观察对象,而在10分钟后订阅时使用了shareReplay ,则可观察对象将返回相同的结果,而不会发出另一个http请求。 Whereas with share , the number of observers returns to 0 after the initial http request finishes. 而使用share ,观察者的数量在初始http请求完成后返回到0。 The future subscribe will trigger another http request 将来的订阅将触发另一个http请求

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM