首页 游戏 软件 资讯 排行榜 专题
首页
数据库
Redis使用LocalStorage的实现示例

Redis使用LocalStorage的实现示例

热心网友
47
转载
2026-04-28

1. 为什么需要 Redis 风格的 LocalStorage 封装

在全栈开发的世界里,一个有趣的“割裂”现象常常让开发者感到困扰:后端处理缓存时,Redis 是当仁不让的主力,其简洁而强大的 API 深受喜爱;而到了前端,LocalStorage 则承担着本地数据存储的重任。问题来了——这两者的操作接口差异可不小。对于习惯了前端开发,又想向全栈领域拓展的同学来说,这往往意味着额外的学习成本和思维切换。

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

那么,有没有一种方法能弥合这道鸿沟呢?答案就是封装一个 Redis 风格的 LocalStorage 工具类。这么做,至少能带来几个显而易见的好处:

  • 统一操作体验:前后端缓存操作接口保持一致,降低心智负担。
  • 功能增强:为 LocalStorage 补上原生缺失的“高级”功能,比如精确的过期时间管理、键名通配符查找等。
  • 提升代码质量:集中化的工具类让代码更整洁、更易维护,可读性也大大增强。
  • 面向未来:为日后可能的架构调整(比如将部分缓存逻辑迁移到后端)提前铺平道路,代码适应性更强。

Redis使用LocalStorage的实现示例

2. 核心功能实现与代码解析

完整工具类实现

export abstract class CacheUtil {
  /**
   * 设置缓存
   * @param key 缓存键
   * @param value 缓存值
   * @param ttl 过期时间(单位:秒),-1 表示永不过期
   */
  static set(key: string, value: any, ttl: number = -1) {
    const data = { value, ttl: ttl === -1 ? ttl : Date.now() + ttl * 1000 }
    localStorage.setItem(key, JSON.stringify(data))
  }

  /**
   * 获取缓存
   * @param key 缓存键
   * @param defaultValue 缓存不存在或过期时的默认值
   * @returns 缓存值或默认值
   */
  static get(key: string, defaultValue: T | null = null): T | null {
    try {
      const jsonStr = localStorage.getItem(key)
      if (!jsonStr) return defaultValue

      const data = JSON.parse(jsonStr)
      if (data.ttl === -1 || Date.now() <= data.ttl) return data.value

      localStorage.removeItem(key)
      return defaultValue
    } catch (error: unknown) {
      localStorage.removeItem(key)
      return defaultValue
    }
  }

  /**
   * 获取缓存剩余过期时间(秒)
   * -1 = 永久有效
   * -2 = 已过期/不存在
   */
  static ttl(key: string): number {
    try {
      const item = localStorage.getItem(key)
      if (!item) return -2

      const data = JSON.parse(item)
      if (data.ttl === -1) return -1

      const remaining = data.ttl - Date.now()
      return remaining > 0 ? Math.floor(remaining / 1000) : -2
    } catch {
      return -2 // 解析失败,视为无效缓存
    }
  }

  /**
   * 动态设置缓存过期时间
   * @param key 缓存键
   * @param ttl 过期时间(秒)
   * @returns 是否设置成功
   */
  static expire(key: string, ttl: number): boolean {
    const value = this.get(key)
    if (value === null) return false
    this.set(key, value, ttl)
    return true
  }

  /**
   * 删除缓存
   * @param key 缓存键
   */
  static del(key: string) {
    localStorage.removeItem(key)
  }

  /**
   * 清空所有缓存
   */
  static flushall() {
    localStorage.clear()
  }

  /**
   * 查找缓存键(支持通配符 *,和 Redis 用法一致)
   * @param pattern 匹配规则,例如 user*、*info、*token*,默认 *
   * @returns 匹配的键数组
   */
  static keys(pattern: string = '*'): string[] {
    const allKeys = Object.keys(localStorage)
    const regex = new RegExp(pattern.replace(/\*/g, '.*'))
    return allKeys.filter((key) => regex.test(key))
  }

  /**
   * 检查缓存是否存在且未过期
   * @param key 缓存键
   * @returns 是否存在有效缓存
   */
  static exists(key: string): boolean {
    return this.get(key) !== null
  }
}

核心设计要点

  1. 数据结构设计:这是整个封装的基石。我们采用 { value, ttl } 这样的结构来包裹实际数据。其中 ttl 字段很关键:它要么是 -1(代表永不过期),要么是一个未来的绝对时间戳(毫秒数)。这样一来,判断过期就变成了简单的时间戳比较。

  2. 过期时间处理:围绕上述数据结构,我们构建了一套完整的生命周期管理:

    • 设置时:根据传入的秒数,计算出精确的过期时间点。
    • 获取时:自动检查是否“寿终正寝”,如果过期则默默清理掉,避免脏数据残留。
    • 查询时:通过 ttl 方法,可以随时查看某个缓存还剩多少“保质期”,非常直观。
  3. 错误处理:LocalStorage 里存储的都是字符串,JSON 解析是必不可少的一步,但也是最容易出错的环节。通过 try-catch 包裹解析逻辑,即使遇到意外格式的数据,也能保证程序不会崩溃,而是返回预设的默认值并清理无效条目,确保了整体的健壮性。

  4. Redis 风格 API:为了让后端同学感到亲切,我们几乎1:1复刻了 Redis 的常用命令:set, get, del, expire, keys, exists。用起来几乎感觉不到差别。

  5. 通配符支持keys 方法是亮点之一。它支持使用 * 进行模糊匹配,比如 user* 可以找出所有以 “user” 开头的键。其内部通过将通配符模式转换为正则表达式来实现,用法和效果都与 Redis 保持一致。

3. 完整 API 接口说明

方法 功能描述 参数说明 返回值
set(key, value, ttl) 设置缓存 key: 缓存键
value: 缓存值
ttl: 过期时间(秒),默认 -1
get(key, defaultValue) 获取缓存 key: 缓存键
defaultValue: 默认值,默认 null
缓存值或默认值
ttl(key) 获取剩余过期时间 key: 缓存键 -1: 永久有效
-2: 已过期/不存在
正数: 剩余秒数
expire(key, ttl) 设置过期时间 key: 缓存键
ttl: 过期时间(秒)
是否设置成功
del(key) 删除缓存 key: 缓存键
flushall() 清空所有缓存
keys(pattern) 查找匹配的键 pattern: 匹配规则,默认 * 匹配的键数组
exists(key) 检查缓存是否存在 key: 缓存键 是否存在有效缓存

4. 实战使用示例

基础操作

// 设置一个用户缓存,1小时后自动过期
CacheUtil.set('USER', { id: 1, name: 'John' }, 3600)

// 需要时,轻松获取
const user = CacheUtil.get('USER')
console.log(user) // 输出:{ id: 1, name: 'John' }

过期时间管理

// 假设用户活动频繁,我们想给缓存续个期,再延长2小时
CacheUtil.expire('USER', 7200)

// 随时查看缓存还剩多少“寿命”
const remainingTime = CacheUtil.ttl('USER')
console.log(`剩余过期时间:${remainingTime}秒`)

键管理

// 使用通配符查找相关键,管理起来非常方便
const userKeys = CacheUtil.keys('USER*') // 找到所有USER开头的键
const infoKeys = CacheUtil.keys('*INFO') // 找到所有INFO结尾的键
console.log('用户相关键:', userKeys)
console.log('信息相关键:', infoKeys)

// 快速检查某个关键缓存是否还在
const exists = CacheUtil.exists('USER')
console.log('USER 缓存存在:', exists)

删除操作

// 删除单个缓存项
CacheUtil.del('USER')

// 一键清空,适用于用户退出登录等场景
CacheUtil.flushall()

5. 性能考量与最佳实践

性能考量

  • 存储限制:别忘了,LocalStorage 通常有 5MB 左右的容量上限。存储大型对象或海量数据前,最好先掂量一下。
  • 读取性能:频繁读取体积庞大的 JSON 对象,解析开销不容忽视。合理的建议是:按需存储,把大数据拆分成小块。
  • 过期检查:每次 get 操作都附带一次时间戳比对,虽然开销很小,但在极端高频的调用下也需要纳入考量。
  • JSON 序列化:存进去要 stringify,拿出来要 parse。对于结构复杂、嵌套深的对象,这个成本会线性增长。所以,存储的数据结构还是尽量保持扁平为好。

最佳实践

  • 命名规范:为缓存键设立统一的前缀(比如 APP_USER_INFO),这是避免项目内甚至跨第三方库键名冲突的最简单有效的方法。
  • 数据类型:LocalStorage 不是状态管理库。只存那些真正需要持久化的、关键的用户数据或配置,别把整个应用的状态都往里塞。
  • 过期策略:给临时数据(如表单草稿、会话信息)设置一个合理的过期时间,让系统能自动清理,这是保持存储空间健康的好习惯。
  • 错误处理:工具类内部已经做了基础防护,但在业务代码调用时,尤其是在获取关键配置或用户信息时,考虑一下缓存缺失的降级方案,总是更稳妥的。
  • 安全注意:这一点必须强调:LocalStorage 对同源脚本完全开放,极易受到 XSS 攻击。因此,绝对不要将密码、敏感令牌等机密信息存入其中。
来源:https://www.jb51.net/database/362957civ.htm
免责声明: 游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

最新APP

宝宝过生日
宝宝过生日
应用辅助 04-07
台球世界
台球世界
体育竞技 04-07
解绳子
解绳子
休闲益智 04-07
骑兵冲突
骑兵冲突
棋牌策略 04-07
三国真龙传
三国真龙传
角色扮演 04-07

热门推荐

霸王茶姬回应顾客喝出水银:高度重视 一切以调查结果为准
业界动态
霸王茶姬回应顾客喝出水银:高度重视 一切以调查结果为准

霸王茶姬回应顾客喝出疑似水银物质:门店称流程不可能出现,正配合调查 近日,一则关于新茶饮的消费纠纷引发了广泛关注。据媒体报道,安徽宿州一位消费者反映,其在霸王茶姬砀山万达广场门店购买的饮品中,发现了疑似水银的液态金属物质。 根据消费者描述,事情始于饮用时尝到的异常颗粒感。随后仔细查看,竟在杯底发现了

热心网友
04.28
车身升高、中控屏加大!二代哈弗H9 2026款上市:17.49万起
业界动态
车身升高、中控屏加大!二代哈弗H9 2026款上市:17.49万起

2026款哈弗H9正式上市:硬派越野的全面进阶 4月28日,备受关注的2026款哈弗H9公布了最新动态。新车指导价定在19 99万至24 79万元区间,并推出了颇具吸引力的限时换新价——17 49万元起,顶配车型也仅需22 29万元。这个价格策略,无疑让硬派越野的门槛变得更亲民了。 外观:硬朗气场再

热心网友
04.28
Ubuntu系统Java路径怎么配置
编程语言
Ubuntu系统Java路径怎么配置

在Ubuntu系统中配置Ja va路径 在Ubuntu系统里配置Ja va环境,其实是个挺常见的需求。这事儿说简单也简单,核心就两步:设置好JA VA_HOME环境变量,再把Ja va的可执行文件路径加到PATH里。下面咱们就一步步来,把这事儿彻底搞定。 第一步:安装Ja va 如果你系统里还没装J

热心网友
04.28
小米汽车公布五一假期专项售后服务:24小时不限里程免费救援、赠送500打车券
业界动态
小米汽车公布五一假期专项售后服务:24小时不限里程免费救援、赠送500打车券

小米汽车发布五一假期专项售后服务,为车主出行保驾护航 五一假期将至,出行高峰随之而来。就在今天,小米汽车正式发布了针对2026年五一假期的专项售后服务保障方案。这项服务聚焦车主在假期出行中可能遇到的各类突发状况,推出了一系列重磅权益,覆盖了整个假期时段,从4月29日一直持续到5月6日。 此次专项服务

热心网友
04.28
Ubuntu中Java内存设置如何调整
编程语言
Ubuntu中Java内存设置如何调整

在Ubuntu系统中调整Ja va内存设置 在Ubuntu系统上运行Ja va应用,内存配置是个绕不开的话题。调得好,应用跑得飞快;调得不对,性能瓶颈甚至崩溃都可能找上门。好在调整方法并不复杂,关键得找准场景。下面这张图,可以帮你快速建立起一个直观的印象: 接下来,咱们就聊聊几种主流的调整路径,你可

热心网友
04.28