我定义了一个拦截器来缓存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);这里缺少的是,如果请求处于挂起状态,则不处理该请求,而是等待请求在缓存中就绪并返回。
让这个逻辑适应这个问题的最好方法是什么?
发布于 2018-05-24 17:29:34
你的意思是在do()函数中,并行请求会出现什么问题?例如,2个请求使用相同的url,然后这两个请求将被发送到服务器并放到缓存中?
这个怎么样?不是把HttpResponse放到缓存中,而是把那个可观察到的对象放进去。如下所示:
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);发布于 2018-05-24 19:02:10
我使用cache dict和queue dict和share运算符解决了这个问题,如下所示:
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);发布于 2018-08-30 15:33:16
你可以尝试使用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);https://stackoverflow.com/questions/50505085
复制相似问题