概览
简介
@keq-request/cache 是一个轻量的传输层请求缓存中间件。它在请求发出前后介入,独立于 UI 框架和运行时环境工作——无论是浏览器、Node.js、React Native 还是小程序,都能提供一致的缓存能力。
核心特性
- 🎯 多种缓存策略 - Network First、Cache First、Stale-While-Revalidate、Network Only,并支持自定义策略和策略组合
- 💾 多层存储架构 - 内存、IndexedDB、多级缓存联动,内置 LRU/LFU/TTL/Random 淘汰策略
- 🔒 请求串行化 - 同一缓存键的并发请求自动排队,避免缓存击穿和重复请求
- 📡 可观测 - cache:hit / cache:miss / cache:update 事件 + Server-Timing 响应头
- 🎨 规则化配置 - 全局规则匹配 + 请求级覆盖,灵活控制粒度
- 🔧 可扩展 - 自定义缓存策略函数、自定义存储实现
快速开始
基础用法
import { request } from "keq"
import { cache, MemoryStorage } from "@keq-request/cache"
// 创建存储实例
const storage = new MemoryStorage()
// 使用缓存中间件
// 默认不会缓存任何请求
request.use(cache({ storage }))
// 发起请求
request
.get("/api/data")
// 启用缓存
.option('cache', {
key: '/api/data',
strategy: Strategy.CACHE_FIRST,
ttl: 60, // 缓存 60 秒
})配置缓存规则
import { request } from "keq"
import { cache, Strategy, MemoryStorage } from "@keq-request/cache"
request.use(
cache({
storage: new MemoryStorage(),
rules: [
{
// 匹配所有 GET 请求
pattern: (ctx) => ctx.request.method === "get",
// 使用 SWR 策略
strategy: Strategy.STALE_WHILE_REVALIDATE,
// 缓存有效期 5 分钟
ttl: 5 * 60,
// 自定义缓存键
key: (ctx) => ctx.request.__url__.href,
// 排除非 200 响应
exclude: async (response) => response.status !== 200,
},
],
})
)请求级别配置
可以在发起请求时覆盖全局配置:
import { request } from "keq"
import { Strategy } from "@keq-request/cache"
request
.get("/cats")
// 覆盖全局缓存配置
.options({
cache: {
strategy: Strategy.NETWORK_FIRST,
key: 'custom-cache-key',
// 未设置的属性将使用全局配置
// exclude: async (response) => response.status !== 200,
ttl: 60,
},
})
// 也可以禁止缓存
.option('cache', false)配置项
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| storage | KeqCacheStorage | - | 缓存存储实例,详见 Storage |
| keyFactory | (context) => string | (context) => context.locationId | 缓存键生成函数,生成相同 key 的请求将共享缓存 |
| serverTiming | boolean | false | 是否在响应头中添加 Server-Timing |
| rules | Rule[] | [] | 缓存规则数组 |
rules
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| pattern | boolean | (ctx) => boolean | true | 匹配规则,用于判断请求是否应用此缓存规则 |
| key | (ctx) => string | 使用全局 keyFactory | 自定义缓存键生成函数 |
| strategy | Strategy | Strategy.NETWORK_FIRST | 缓存策略,详见 缓存策略 |
| ttl | number | Infinity | 缓存有效期(秒) |
| concurrent | boolean | false | 是否允许同 key 请求并发执行。为 false 时同 key 请求排队串行执行 |
| exclude | (response) => boolean | Promise<boolean> | - | 排除函数,返回 true 时不缓存该响应 |
| serverTiming | boolean | false | 是否在响应头中添加 Server-Timing |
扩展项
.on(eventName, callback)
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| cache:hit | 缓存命中时触发 | ({ key: string, response: Response, context: KeqContext }) |
| cache:miss | 缓存未命中时触发 | ({ key: string, context: KeqContext}) |
| cache:update | 缓存更新时触发 | ({ key: string, oldResponse: Response, newResponse: Response, context: KeqContext }) |
.option('cache', options)
| 参数名 | 类型 | 说明 |
|---|---|---|
| key | (ctx) => string | 自定义缓存键生成函数 |
| debug | boolean | 打印调试日志 |
| strategy | Strategy | 缓存策略,详见 缓存策略 |
| ttl | number | 缓存有效期(秒) |
| concurrent | boolean | 是否允许同 key 请求并发执行。默认 false,同 key 请求将排队串行执行以避免缓存击穿 |
| exclude | (response) => boolean | Promise<boolean> | 排除函数,返回 true 时不缓存该响应 |
| serverTiming | boolean | 是否在响应头中添加 Server-Timing |