localStorage缓存 接口 配置

news2024/11/27 16:04:12

localStorage缓存 接口 配置

  • 封装缓存函数
  • 接口缓存
  • 配置缓存

封装缓存组件 统一管理缓存设置 减少请求 优化逻辑

封装缓存函数

缓存的键和时间也可以放在一起,更好统一管理。

// 缓存键前缀
const PREFIX = 'diamond_'

// 缓存时间配置(毫秒)
const CACHE_TIME = {
  SHORT: 5 * 60 * 1000,        // 5分钟
  MEDIUM: 30 * 60 * 1000,      // 30分钟
  LONG: 24 * 60 * 60 * 1000,   // 1天
  WEEK: 7 * 24 * 60 * 60 * 1000 // 1周
}

// 缓存版本号,用于缓存更新
const CACHE_VERSION = '1.0.0'

export const cache = {
  // 设置缓存 默认过期时间30分钟
  set(key, value, expire = CACHE_TIME.MEDIUM) {
    const data = {
      value,
      expire: expire ? Date.now() + expire : null,
      version: CACHE_VERSION
    }
    try {
      localStorage.setItem(PREFIX + key, JSON.stringify(data))
      return true
    } catch (e) {
      // 如果存储失败(存储已满),清理过期缓存后重试
      if (e.name === 'QuotaExceededError') {
        this.clearExpired()
        try {
          localStorage.setItem(PREFIX + key, JSON.stringify(data))
          return true
        } catch (e) {
          console.error('Cache storage failed:', e)
          return false
        }
      }
      return false
    }
  },

  // 获取缓存
  get(key) {
    const data = localStorage.getItem(PREFIX + key)
    if (!data) return null

    try {
      const { value, expire, version } = JSON.parse(data)
      // 检查版本号和过期时间
      if (version !== CACHE_VERSION || (expire && Date.now() > expire)) {
        this.remove(key)
        return null
      }
      return value
    } catch {
      this.remove(key)
      return null
    }
  },

  // 移除缓存
  remove(key) {
    localStorage.removeItem(PREFIX + key)
  },

  // 清除所有缓存
  clear() {
    Object.keys(localStorage).forEach(key => {
      if (key.startsWith(PREFIX)) {
        localStorage.removeItem(key)
      }
    })
  },

  // 清除过期缓存
  clearExpired() {
    Object.keys(localStorage).forEach(key => {
      if (key.startsWith(PREFIX)) {
        try {
          const data = JSON.parse(localStorage.getItem(key))
          if (data.version !== CACHE_VERSION || (data.expire && Date.now() > data.expire)) {
            localStorage.removeItem(key)
          }
        } catch {
          localStorage.removeItem(key)
        }
      }
    })
  },

  // 获取缓存大小(字节)
  size() {
    let size = 0
    Object.keys(localStorage).forEach(key => {
      if (key.startsWith(PREFIX)) {
        size += localStorage.getItem(key).length * 2 // UTF-16 编码每个字符占2字节
      }
    })
    return size
  },

  // 检查缓存是否可用
  isAvailable() {
    try {
      const testKey = PREFIX + 'test'
      localStorage.setItem(testKey, 'test')
      localStorage.removeItem(testKey)
      return true
    } catch {
      return false
    }
  },

  // 获取所有缓存键
  keys() {
    return Object.keys(localStorage)
      .filter(key => key.startsWith(PREFIX))
      .map(key => key.slice(PREFIX.length))
  },

  // 批量设置缓存
  setMany(items, expire = CACHE_TIME.MEDIUM) {
    return items.every(({ key, value }) => this.set(key, value, expire))
  },

  // 批量获取缓存
  getMany(keys) {
    return keys.map(key => ({ key, value: this.get(key) }))
  },

  // 批量删除缓存
  removeMany(keys) {
    keys.forEach(key => this.remove(key))
  }
}

// 缓存键定义
export const CACHE_KEYS = {
  USER_INFO: 'user_info',
  DIAMOND_LIST: 'diamond_list',
  DIAMOND_DETAIL: 'diamond_detail_',
  FILTER_OPTIONS: 'filter_options',
  LANGUAGE: 'language',
  MENU_STATE: 'menu_state',
  THEME: 'theme',
  USER_PREFERENCES: 'user_preferences'
}

// 缓存时间定义
export const CACHE_EXPIRES = {
  USER_INFO: CACHE_TIME.WEEK,
  DIAMOND_LIST: CACHE_TIME.SHORT,
  DIAMOND_DETAIL: CACHE_TIME.MEDIUM,
  FILTER_OPTIONS: CACHE_TIME.LONG,
  LANGUAGE: CACHE_TIME.LONG,
  MENU_STATE: CACHE_TIME.LONG,
  THEME: CACHE_TIME.LONG,
  USER_PREFERENCES: CACHE_TIME.LONG
}

// 定期清理过期缓存(每小时)
if (typeof window !== 'undefined') {
  setInterval(() => {
    cache.clearExpired()
  }, 60 * 60 * 1000)
}

export default cache 

接口缓存

减少每次刷新或跳转进行数据请求,也可以进行二次封装减少代码量

import { cache, CACHE_KEYS, CACHE_EXPIRES } from '@/utils/cache'

// 获取钻石列表
export function getDiamondPage(params) {
  // 生成缓存键
  const cacheKey = CACHE_KEYS.DIAMOND_LIST + JSON.stringify(params)
  // 尝试从缓存获取
  const cachedData = cache.get(cacheKey)
  if (cachedData) {
    return Promise.resolve(cachedData)
  }
  // 发起请求
  return request({
    url: '/admin-api/bs/diamond/page',
    method: 'post',
    data: params
  }).then(res => {
    if (res.code === 0) {
      // 设置缓存
      cache.set(cacheKey, res, CACHE_EXPIRES.DIAMOND_LIST)
    }
    return res
  })
}

配置缓存

// 获取配置信息
const getCurrentLanguage = () => {
  const cachedLang = cache.get(CACHE_KEYS.LANGUAGE)
  if (cachedLang) return cachedLang
  
  const browserLang = navigator.language.toLowerCase()
  return browserLang.includes('zh') ? 'zh-CN' : 'en-US'
}
// 设置配置信息
cache.set(CACHE_KEYS.LANGUAGE, locale, CACHE_EXPIRES.LANGUAGE)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2248505.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Perforce SAST专家详解:自动驾驶汽车的安全与技术挑战,Klocwork、Helix QAC等静态代码分析成必备合规性工具

自动驾驶汽车安全吗?现代汽车的软件包含1亿多行代码,支持许多不同的功能,如巡航控制、速度辅助和泊车摄像头。而且,这些嵌入式系统中的代码只会越来越复杂。 随着未来汽车的互联程度越来越高,这一趋势还将继续。汽车越…

(计算机组成原理)期末复习

第一章 计算机的基本组成:硬件软件(程序)计算机系统 软件有系统软件(系统管理工具),应用软件 计算机硬件:包括主机和外设,主机包括CPU和内存,***CPU由运算器和控制器所组…

UEFI 中的 Protocol

Protocol 在 UEFI 内核中的表示 typedef VOID *EFI_HANDLE;EFI_HANDLE是指向某种对象的指针,UEFI 用它来表示某个对象。 UEFI 扫描总线后,会为每个设备建立一个 Controller 对象,用于控制设备,所有该设备的驱动以 Protocol 的形式…

量子安全与经典密码学:一些现实方面的讨论

量子安全与经典密码学 背景:量子安全与经典密码学量子计算对传统密码学的威胁 安全性分析经典密码学的数学复杂性假设**量子密码学的物理不可克隆性假设** **性能与实现难度**后量子算法在经典计算机上的运行效率**量子通信设备的技术要求与成本** **可扩展性与适用…

【大模型】LLaMA-Factory的环境配置、微调模型与测试

前言 【一些闲扯】 时常和朋友闲聊,时代发展这么快,在时代的洪流下,我们个人能抓住些什么呢。我问了大模型,文心一言是这样回答的: 在快速发展的时代背景下,个人确实面临着诸多挑战,但同时也充满…

PostgreSQL的学习心得和知识总结(一百五十八)|在线调优工具pgtune的实现原理和源码解析

目录结构 注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下: 1、参考书籍:《PostgreSQL数据库内核分析》 2、参考书籍:《数据库事务处理的艺术:事务管理与并发控制》 3、PostgreSQL数据库仓库…

汽车渲染领域:Blender 和 UE5 哪款更适用?两者区别?

在汽车渲染领域,选择合适的工具对于实现高质量的视觉效果至关重要。Blender和UE5(Unreal Engine 5)作为两大主流3D软件,各自在渲染动画方面有着显著的差异。本文将从核心定位与用途、工作流程、渲染技术和灵活性、后期处理与合成四…

机器学习—迁移学习:使用其他任务中的数据

对于一个没有那么多数据的应用程序,迁移学习是一种奇妙的技术,它允许你使用来自不同任务的数据来帮助你的应用程序,迁移学习是如何工作的? 以下是迁移学习的工作原理,假设你想识别手写的数字0到9,但是你没…

LeetCode 3206.交替组 I:遍历

【LetMeFly】3206.交替组 I:遍历 力扣题目链接:https://leetcode.cn/problems/alternating-groups-i/ 给你一个整数数组 colors ,它表示一个由红色和蓝色瓷砖组成的环,第 i 块瓷砖的颜色为 colors[i] : colors[i] …

如何通过高效的缓存策略无缝加速湖仓查询

引言 本文将探讨如何利用开源项目 StarRocks 的缓存策略来加速湖仓查询,为企业提供更快速、更灵活的数据分析能力。作为 StarRocks 社区的主要贡献者和商业化公司,镜舟科技深度参与 StarRocks 项目开发,也为企业着手构建湖仓架构提供更多参考…

25A物联网微型断路器 智慧空开1P 2P 3P 4P-安科瑞黄安南

微型断路器,作为现代电气系统中不可或缺的重要组件,在保障电路安全与稳定运行方面发挥着关键作用。从其工作原理来看,微型断路器通过感知电流的异常变化来迅速作出响应。当电路中的电流超过预设的安全阈值时,其内部的电磁感应装置…

目标检测,图像分割,超分辨率重建

目标检测和图像分割 目标检测和图像分割是计算机视觉中的两个不同任务,它们的输出形式也有所不同。下面我将分别介绍这两个任务的输出。图像分割又可以分为:语义分割、实例分割、全景分割。 语义分割(Semantic Segmentation)&…

16 —— Webpack多页面打包

需求&#xff1a;把 黑马头条登陆页面-内容页面 一起引入打包使用 步骤&#xff1a; 准备源码&#xff08;html、css、js&#xff09;放入相应位置&#xff0c;并改用模块化语法导出 原始content.html代码 <!DOCTYPE html> <html lang"en"><head&…

《PH47 快速开发教程》发布

PDF 教程下载位于CSDN资源栏目&#xff08;网页版本文上方&#xff09; 或Gitee&#xff1a;document ss15/PH47 - 码云 - 开源中国

腾讯云OCR车牌识别实践:从图片上传到车牌识别

在当今智能化和自动化的浪潮中&#xff0c;车牌识别&#xff08;LPR&#xff09;技术已经广泛应用于交通管理、智能停车、自动收费等多个场景。腾讯云OCR车牌识别服务凭借其高效、精准的识别能力&#xff0c;为开发者提供了强大的技术支持。本文将介绍如何利用腾讯云OCR车牌识别…

C++ 优先算法 —— 无重复字符的最长子串(滑动窗口)

目录 题目&#xff1a; 无重复字符的最长子串 1. 题目解析 2. 算法原理 Ⅰ. 暴力枚举 Ⅱ. 滑动窗口&#xff08;同向双指针&#xff09; 3. 代码实现 Ⅰ. 暴力枚举 Ⅱ. 滑动窗口 题目&#xff1a; 无重复字符的最长子串 1. 题目解析 题目截图&#xff1a; 此题所说的…

[网安靶场] [更新中] UPLOAD LABS —— 靶场笔记合集

GitHub - c0ny1/upload-labs: 一个想帮你总结所有类型的上传漏洞的靶场一个想帮你总结所有类型的上传漏洞的靶场. Contribute to c0ny1/upload-labs development by creating an account on GitHub.https://github.com/c0ny1/upload-labs 0x01&#xff1a;UPLOAD LABS 靶场初识…

安装python拓展库pyquery相关问题

我采用的是离线whl文件安装, 从官方库地址: https://pypi.org/, 下载whl文件, 然后在本地电脑上执行pip install whl路径文件名.whl 但是在运行时报错如下图 大体看了看, 先是说了说找到了合适的 lxml>2.1, 在我的python库路径中, 然后我去看了看我的lxml版本, 是4.8.0, 对…

春秋云境 CVE 复现

CVE-2022-4230 靶标介绍 WP Statistics WordPress 插件13.2.9之前的版本不会转义参数&#xff0c;这可能允许经过身份验证的用户执行 SQL 注入攻击。默认情况下&#xff0c;具有管理选项功能 (admin) 的用户可以使用受影响的功能&#xff0c;但是该插件有一个设置允许低权限用…

图论入门编程

卡码网刷题链接&#xff1a;98. 所有可达路径 一、题目简述 二、编程demo 方法①邻接矩阵 from collections import defaultdict #简历邻接矩阵 def build_graph(): n, m map(int,input().split()) graph [[0 for _ in range(n1)] for _ in range(n1)]for _ in range(m): …