我正在尝试使用下一个方法将从API返回的数据存储在行为主题中,我希望在订阅可观察对象之前这样做。
假设我有一个服务,它具有从API检索一些数据的功能:
getData(): Observable<Data> {
return this.http.get(APIURL);
}
现在,在订阅getData((之前,我想将API返回的内容保存在主题中。我用tap((操作符实现了这一点,但通过阅读文档,tap应该用于副作用,在这种情况下,它看起来不像是副作用。所以我做的是这样的事情:
getData(): Observable<Data> {
return this.http.get(APIURL)
.pipe(tap(data => this.subject.next(data));
}
我这样做是为了拥有某种缓存,这样我就不必再次调用API并在数据更新时对其进行一些操作。例如,假设我通过更新查询向该数据添加一个元素,现在我可以更新主题中存储的以前的数据,这样一切都是最新的。只有刷新页面,我才会再次调用API。
我不清楚的是水龙头操作器的用途,这样使用它可以吗?或者我想做的事情有更好的替代方案吗?
如果我理解正确,你可以检查一下,你在主题中是否有一些数据
subject = new BehaviorSubject<any>(null);
getData(): Observable<Data> {
if (subject.getValue()) {
return of(subject.getValue());
}
return this.http.get(APIURL)
.pipe(tap(data => this.subject.next(data));
}
这里有一个CodeSandbox,它显示了在不使用状态管理库的情况下管理缓存请求流的一种方法。
演示的本质是以下
interface IArticle {
title: string;
content: string;
}
@Injectable({ providedIn: "root" })
export class HttpDemoCache {
// You need a variable where to store the data
cachedArticleResponse$: BehaviorSubject<IArticle[]> = new BehaviorSubject([]);
...
loadArticles(someQuery) {
// You need a method that fetches the data from the BE
this.httpClient.get(...).subscribe((x) => {
this.cachedArticleResponse$.next(x);
});
}
updateArticles(newArticle: IArticle) {
// You need a update method to send the new enttity to the back-end + update your cached version
this.http.post(...., {newArticle}).pipe(
switchMap(response =>
this.cachedArticleResponse$
.pipe(
take(1),
tap(cachedArtilces => this.cachedArticleResponse$
.next([...cachedArticles, newArticle]))
)
)
).subscribe()
});
}
}
使用这个解决方案,您几乎可以创建自己的状态管理解决方案,其职责是处理所有cahce/fetch/upload/delete逻辑。
此解决方案的好处是,与直接在组件中获取数据相比,您可以更好地控制正在发生的事情。
**旁注:请记住,这只是一个概念的简单示例,而不是一个详细的解决方案。