如何修改Angular 5.2的CacheInterceptor仅缓存最近3秒请求
修改Angular 5.2缓存拦截器实现3秒有效期逻辑
我来帮你搞定这个需求!核心思路就是给每个缓存条目加上时间戳标记,每次请求过来时先判断缓存是否在3秒有效期内,符合条件就用缓存,否则清空旧缓存并重新发起请求。下面是具体的实现步骤和代码示例:
1. 定义缓存条目结构
首先我们需要一个带时间戳的缓存对象,用来存储响应数据和缓存的时间:
interface CacheEntry { timestamp: number; response: HttpResponse<any>; }
2. 改造缓存拦截器
在你的拦截器里,我们用Map来存储缓存(比普通对象更适合处理键值对),然后在拦截请求时添加时间校验逻辑:
import { Injectable } from '@angular/core'; import { HttpRequest, HttpResponse, HttpHandler, HttpEvent, HttpInterceptor, HTTP_INTERCEPTORS } from '@angular/common/http'; import { Observable, of } from 'rxjs'; import { tap } from 'rxjs/operators'; @Injectable() export class CacheInterceptor implements HttpInterceptor { // 缓存存储:键是请求的唯一标识(URL+参数),值是带时间戳的缓存条目 private cache = new Map<string, CacheEntry>(); // 缓存有效期:3000毫秒=3秒 private readonly CACHE_TTL = 3000; intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // 只缓存GET请求,根据你的需求调整 if (request.method !== 'GET') { return next.handle(request); } // 生成请求的唯一键:URL + 参数序列化(避免相同URL不同参数的请求混淆) const cacheKey = this.generateCacheKey(request); // 检查缓存是否存在且在有效期内 const cachedEntry = this.cache.get(cacheKey); if (cachedEntry) { const now = Date.now(); // 判断当前时间和缓存时间的差是否小于3秒 if (now - cachedEntry.timestamp < this.CACHE_TTL) { console.log(`返回3秒内的缓存数据:${cacheKey}`); // 返回缓存的响应(克隆避免修改原始对象) return of(cachedEntry.response.clone()); } else { // 缓存过期,删除旧缓存 this.cache.delete(cacheKey); console.log(`缓存已过期,重新请求:${cacheKey}`); } } // 没有有效缓存,发起请求并缓存响应 return next.handle(request).pipe( tap(event => { if (event instanceof HttpResponse) { // 存储响应和当前时间戳 this.cache.set(cacheKey, { timestamp: Date.now(), response: event.clone() }); console.log(`缓存新的响应:${cacheKey}`); } }) ); } // 生成请求的唯一标识,处理URL和查询参数 private generateCacheKey(request: HttpRequest<any>): string { // 序列化查询参数,确保相同URL不同参数生成不同的键 const params = request.params.toString(); return `${request.url}?${params}`; } } // 提供拦截器 export const CacheInterceptorProvider = { provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true };
3. 关键逻辑说明
- 缓存键生成:用
URL + 查询参数作为唯一键,避免相同URL不同参数的请求共用缓存,比如/api/data?id=1和/api/data?id=2会生成不同的键。 - 时间校验:每次请求时计算当前时间和缓存时间的差值,小于3秒就返回缓存,否则删除旧缓存并重新请求。
- 响应克隆:因为
HttpResponse是不可变对象,所以返回缓存时要调用clone()方法,避免后续操作修改原始缓存数据。
4. 注册拦截器
最后别忘了在你的AppModule里注册这个拦截器:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HttpClientModule } from '@angular/common/http'; import { CacheInterceptorProvider } from './cache.interceptor'; import { AppComponent } from './app.component'; @NgModule({ declarations: [AppComponent], imports: [BrowserModule, HttpClientModule], providers: [CacheInterceptorProvider], bootstrap: [AppComponent] }) export class AppModule { }
这样修改后,你的缓存拦截器就只会返回最近3秒内的查询请求缓存,超过3秒的请求会自动重新发起啦!
内容的提问来源于stack exchange,提问作者Gurkenkönig
相关产品推荐
相关产品推荐

