我已经定义了一个拦截器来缓存API响应:
if (req.method == 'GET') {
// return cached object if exists
const cachedResponse = this.cache.get(req) || null;
if (cachedResponse) {
return Observable.of(cachedResponse);
}
// call api and cache result if doesn't exist
return next.handle(req).do(event => {
if (event instanceof HttpResponse) {
this.cache.put(req, event)
}
});
}
return next.handle(req);
这里缺少的是,如果请求处于待处理状态,请不要处理该请求,但要等待请求在缓存上准备好并返回它。
使这种逻辑适应这个问题的最佳方法是什么?
答案 0 :(得分:0)
你的意思是你的do()函数,并行请求会遇到什么问题?比如,2个请求使用相同的url,那么这两个请求都将被发送到服务器并放入缓存?
这个怎么样?不要将HttpResponse放在缓存中,而是放置Observable对象。像这样:
if (req.method == 'GET') {
// return cached object if exists
const cachedResponse = this.cache.get(req) || null;
if (cachedResponse) {
return cachedResponse); // it is Observable, even same req in the sam,e time, the second will get a Observable data.
}
// call api and cache result if doesn't exist
const result = next.handle(req);
this.cache.put(req, result)
result.do(event => {
if (event !instanceof HttpResponse) {
this.cache.remove(req) // if it is error, maybe remove?
}
return result;
});
}
return next.handle(req);
答案 1 :(得分:0)
我已经解决了使用缓存dict和队列dict与共享运算符的问题,如下所示:
if (req.method == 'GET') {
// return cached object if exists
const cachedResponse = this.cache.get(req) || null;
if (cachedResponse) {
return Observable.of(cachedResponse);
}
const pendingResponse = this.queue.get(req) || null;
if (pendingResponse) {
return pendingResponse;
}
// call api and cache result if doesn't exist
var obs = next.handle(req).do(event => {
if (event instanceof HttpResponse) {
this.cache.put(req, event)
this.queue.clear(req.urlWithParams)
}
}).share();
this.queue.put(req, obs)
return obs
}
return next.handle(req);
答案 2 :(得分:0)
如果请求处于待处理状态,您可以尝试使用shareReplay
-同一请求将被重用,如果请求已完成-将发出最后一个值。
if (req.method == 'GET') {
if (!this.cache.get(req)) {
const cached = next.handle(req).shareReplay();
this.cache.put(req, cached);
}
return this.cache.get(req);
}
return next.handle(req);