首页 文章

Angular Observable被多次调用

提问于
浏览
0

我有一个服务,我在其中定义了一个全局observable,如下所示:

@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;
    }

现在在我的几个组件中,我在构造函数或ngOnInit中调用getLocation函数,如下所示:

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

我的期望是对ipinfo.io的请求只会进行一次 . 然而,这没有发生 . 从网络日志中我可以看到对ipinfo的请求正在进行多次 . 看起来是一些时间问题 . 如果我在构造函数中添加调试器或console.log语句,则只调用一次 . 但是,发送了多个请求 .

1 回答

  • 5

    您可以使用rxjs share运算符 . 这将确保后续订阅者将共享相同的可观察序列(直到观察者的数量返回到0)

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

    您也可以使用shareReplay运算符 . 不同之处在于将来可以为任何订户存储可观察的结果 . 例如,假设您在应用加载时订阅了observable,当您在10分钟后订阅时 shareReplay ,observable将返回相同的结果而不再发出另一个http请求 . 而对于 share ,观察者的数量在初始http请求完成后返回0 . 未来的订阅将触发另一个http请求

相关问题