[英]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.