我有一个特定于我的项目中的某种数据类型的角度服务。现在,它只是将所有内容直接传递到处理 HTTP 请求的通用数据服务。
@Injectable({
providedIn: 'root',
})
export class QuestionLibraryService {
private readonly dataSvc = inject(DataService);
getAll(): Observable<Array<IQuestionLibrary>> {
return this.dataSvc.questionLibraryGetAll();
}
getOne(libraryId: string): Observable<IQuestionLibrary> {
return this.dataSvc.questionLibraryGet(libraryId);
}
//create, delete, update, etc...
}
我想缓存此服务接收到的数据,以便在应用程序导航时减少 HTTP 调用,并加快速度,这样就不会出现太多短暂的加载状态闪烁。
这是我迄今为止尝试过的方法,这对于
getAll()
方法效果很好,但我不知道该怎么办 getOne()
。
private dataCache: Array<IQuestionLibrary> = [];
getAll(): Observable<Array<IQuestionLibrary>> {
if (this.dataCache.length > 0) {
return of(this.dataCache);
}
return this.dataSvc.questionLibraryGetAll().pipe(
tap((libList) => {
this.dataCache = libList;
}),
);
}
getOne(libraryId: string): Observable<IQuestionLibrary> {
const found = this.getAll().pipe(
map(list => list.find(item => item.id === libraryId))
);
//This is not right...
if (found) {
return found;
}
}
getOne()
应该获取所有项目,以便可以缓存它们,这是对当前行为的更改,当前行为调用单独的 URL 来获取单个项目。我可以放弃那个而选择这个。
但是现在
found
属于Observable<IQuestionLibrary | undefined>
类型,我不知道如何检查是否确实找到了某个项目,因为它是可观察的。
我需要它返回单个找到的项目,或者抛出错误。我怎样才能让它做到这一点?另外,对于如何在服务中缓存这样的数据,我是否走在正确的轨道上?
getAll(): Observable<Array<IQuestionLibrary>> {
return this.dataSvc.questionLibraryGetAll().pipe(
// catch error when nothing found - works only when service http request throws also error when nothing found - you can use catchError() also in DataService
catchError((error) => {
return throwError(error);
}),
// returns always the last value - no other caching needed
shareReplay(1)
);
}
捕获错误
https://rxjs.dev/api/operators/catchError
分享重播 https://rxjs.dev/api/operators/shareReplay\ 关于 shareReplay 的好文章:https://careydevelopment.us/blog/angular-use-sharereplay-to-cache-http-responses-from-downstream-services