You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:02:03