Angular Observable 被多次调用
Angular Observable being called multiple times
我有一个服务,我在其中定义了一个全局可观察对象:
@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 语句,它只会被调用一次。但是发送了不止一个请求。
您可以使用 rxjs share 运算符。这将确保后续订阅者将共享相同的可观察序列(直到观察者数量returns变为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 将 return 相同的结果并且不会发出另一个 http 请求。而对于 share
,初始 http 请求完成后观察者的数量 return 变为 0。未来订阅将触发另一个http请求
我有一个服务,我在其中定义了一个全局可观察对象:
@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 语句,它只会被调用一次。但是发送了不止一个请求。
您可以使用 rxjs share 运算符。这将确保后续订阅者将共享相同的可观察序列(直到观察者数量returns变为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 将 return 相同的结果并且不会发出另一个 http 请求。而对于 share
,初始 http 请求完成后观察者的数量 return 变为 0。未来订阅将触发另一个http请求