我有一个共享服务(从 this 建议开始)在第一次 http 请求后缓存并返回一些数据:
export class SharedService {
constructor(private http:Http) {
}
getData() {
if (this.cachedData) {
return Observable.of(this.cachedData);
} else {
return this.http.get(...)
.map(res => res.json())
.do((data) => {
this.cachedData = data;
});
}
}
}
我的问题是我在同一个模板中有一些指令和组件同时初始化并且每个都同时调用(在 ngInit 函数内)getData 方法(所有这些都在第一个成功之前)等等该服务启动许多 http 请求而不是返回缓存的数据。 有人可以建议我如何避免这种副作用吗?
最佳答案
您的解决方案并未涵盖所有情况。
将其与我在 https://stackoverflow.com/a/36291681/217408 中的方法进行比较
getData() {
if(this.data) {
// if `data` is available just return it as `Observable`
return Observable.of(this.data);
else if(this.observable) {
// if `this.observable` is set then the request is in progress
// return the `Observable` for the ongoing request
return this.observable;
} else {
// create the request, store the `Observable` for subsequent subscribers
this.observable = this.http.get('/someUrl')
.map(res => res.json())
.do(val => {
this.data = val;
// when the cached data is available we don't need the `Observable` reference anymore
this.observable = null;
})
// make it shared so more than one subscriber can get the result
.share();
return this.observable;
}
}
在请求未返回之前,您需要将从第一个请求创建的 Observable
返回到后续请求,直到第一个请求完成。
https://stackoverflow.com/a/36296015/217408还展示了一种有趣的方法,但有一个小缺点(取决于您的要求),即请求无法取消。
同时确保您仅将共享服务注册为提供者一次,如@MichaelD 所述。
Angular 团队建议使用根组件的 providers: [...]
列表而不是 bootstrap(...)
但没有技术原因。他们认为它更易于维护。
关于caching - Angular 2,共享服务http observable中的并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36623788/