[英]Angular service instantiated every time by injection to component
我实现了一项服务,该服务应一次获取数据并缓存结果。 该服务位于根级别。 每当我将此服务注入组件的构造函数中并订阅该方法时,该服务都会发出新的http请求。
我已经尝试过将请求代码从构造函数中移到方法中。
@Injectable({
providedIn: 'root'
})
export class SessionService {
private api = Configuration.api + 'session/';
private readonly session$: Observable<Session>;
constructor(private http: HttpClient) {
this.session$ = this.http
.get<any>(`${this.api}current`, {withCredentials: true})
.pipe(
timeout(Configuration.timeout),
retry(Configuration.retry),
map(data => {
return data.session as Session;
}
),
catchError(ErrorService.handleError)
);
}
getCurrentSession(): Observable<Session> {
return this.session$;
}
}
export class Component implements OnInit, AfterContentInit {
session = Session.empty();
constructor(
private _s: SessionService) {
this._s.getCurrentSession().subscribe(session => this.session = session);
}
}
目的是执行一次请求并将结果缓存在变量中。
可观察对象是流的定义,它们在每个订阅上执行,因此每次您只订阅导致其执行的http请求时。 为了解决这个问题,您需要订阅构造函数并将结果存储在将处理缓存的主题中:
export class SessionService {
private api = Configuration.api + 'session/';
private session$ = new ReplaySubject<Session>(1);
constructor(private http: HttpClient) {
this.loadSession();
}
loadSession() {
this.http
.get<any>(`${this.api}current`, {withCredentials: true})
.pipe(
timeout(Configuration.timeout),
retry(Configuration.retry),
map(data => {
return data.session as Session;
}
),
catchError(ErrorService.handleError)
).subscribe(this.session$);
}
getCurrentSession(): Observable<Session> {
return this.session$.asObservable();
}
}
尽管您也可以这样做:
this.session$ = this.http
.get<any>(`${this.api}current`, {withCredentials: true})
.pipe(
timeout(Configuration.timeout),
retry(Configuration.retry),
map(data => {
return data.session as Session;
}
),
catchError(ErrorService.handleError),
shareReplay(1)
);
shareReplay运算符或多或少执行完全相同的操作。 我之所以喜欢我建议的原始方法,是因为它提供了一种更简便的方法,可以在需要时强制重新加载数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.