最近,我使用HttpInterceptor在Angular 6应用程序中使用了一个缓存。它将响应记录在内存中,并在响应存在TTL的情况下为它们提供服务。但是我有一个问题,其中发出Http请求的程序代码使用map运算符来修改检索到的数据,因此以某种方式将其保存到缓存中。如何做到这一点,以便从服务器中检索到的HttpResponse对象从服务器检索并将它们存储在缓存后不会以任何方式发生突变?
我创建了一个演示该问题的堆栈闪电:
https://stackblitz.com/edit/angular-caching-mutation
从缓存中提供响应后,它将被拆分成一个数组,就像映射操作发生在将服务器响应保存到缓存中之前一样。
Fetcher服务进行HTTP调用并更改响应:
getData() {
return this.http.get('https://jsonplaceholder.typicode.com/todos/1')
.pipe(map(next => {
next['title'] = next['title'].split('u');
return next;
}));;
}
拦截器:
const TTL = 5;
@Injectable()
export class CacheInterceptor implements HttpInterceptor {
constructor(private cache: GetCacheService) {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (!(request.method === 'GET')) {
return next.handle(request);
} else {
console.log('Checking cache for data.');
const cachedResponse = this.cache.get(request.url);
return cachedResponse ? of(cachedResponse) : this.handleRequest(request, next);
}
}
private handleRequest(
request: HttpRequest<any>,
next: HttpHandler
) {
return next.handle(request).pipe(tap(event => {
if (event instanceof HttpResponse) {
this.cache.set(request.url, event, TTL);
}
}));
}
}
缓存服务:
@Injectable({
providedIn: 'root'
})
export class GetCacheService {
private cache = new Map<string, [Date, HttpResponse<any>]>();
constructor() {
}
get(key: string): HttpResponse<any> {
const tuple = this.cache.get(key);
if (!tuple) {
return null;
}
const expires = tuple[0];
const httpResponse = tuple[1];
// check if cached HttpResponse is expired, if it is, delete
// it and respond as if we had nothing cached
const now = new Date();
if (expires && expires.getTime() < now.getTime()) {
this.cache.delete(key);
return null;
}
console.log('Retrieved from cache!');
console.log(httpResponse);
console.log('The above cached HttpResponse object has been mutated by the mapping function in fetcher.service.ts');
return httpResponse;
}
set(key: string, value: HttpResponse<any>, ttl = null) {
if (ttl) {
const expires = new Date();
expires.setSeconds(expires.getSeconds() + ttl);
this.cache.set(key, [expires, value]);
} else {
this.cache.set(key, [null, value]);
}
return true;
}
}
答案 0 :(得分:0)
内部缓存服务中的get()
您将返回引用相同对象实例的原始缓存对象,如果对其进行修改,它将被更改。您可以使用此代码
get(key: string): HttpResponse<any> {
.....
return Object.assign({}, httpResponse);
}