当前位置: 首页 > news >正文

HarmonyOS CacheUtil 进阶:缓存设计模式与典型应用场景

文章目录

    • 背景
    • 一、CacheUtil 的应用层次
    • 二、模式一:安全读取模式
    • 三、模式二:惰性初始化(Lazy Load)
    • 四、模式三:ClickUtil 防抖的依赖关系
    • 五、模式四:防重复请求标记
    • 六、模式五:退出登录时清理
    • 七、缓存 UI 展示
    • 八、CacheUtil 的局限性
    • 九、命名规范建议
    • 十、小结

背景

近期发现一款很有意思的HarmonyOS 三方库, 地址 @pura/harmony-utils(V1.4.0) , 作者是"桃花镇童长老", 我这里也是直接通过该作者公布的源码进行案例编写进行,写了到目前写了一部分demo ,感觉确实很有帮助,这里呢也是开始写一个系列的演示demo 供大家参考。如有帮助可以在OpenHarmony中进行下载安装进行使用哦

案例demo导航展示

↓↓↓↓↓↓接下来言归正传 ↓↓↓↓

一、CacheUtil 的应用层次

CacheUtil看起来只是一个简单的键值存储,但在实际开发中可以承担多种角色:

  1. 工具基础设施:作为其他工具类的底层存储(如ClickUtil的防抖)
  2. 页面级缓存:同一页面多次访问的数据缓存
  3. 跨组件状态共享:替代简单的全局变量
  4. 防重复请求:标记正在进行的网络请求,防止重复发起

效果演示

二、模式一:安全读取模式

最常见的缓存读取方式应该配合has()判断:

// 不推荐:直接 get,可能返回 undefinedconsttoken=CacheUtil.get<string>('userToken');// 如果 token 为 undefined,后续使用会报错// 推荐:先 has 再 getif(CacheUtil.has('userToken')){consttoken=CacheUtil.get<string>('userToken');// 安全使用 token}else{// 处理不存在的情况}

Demo 中也遵循了这个模式:

cacheGet(){if(this.cacheKeyInput.trim()===''){this.addLog('Cache','请输入 Key','warn');return;}consthas=CacheUtil.has(this.cacheKeyInput.trim());if(!has){this.addLog('Cache',`Key "${this.cacheKeyInput}" 不存在`,'warn');return;}constval=CacheUtil.get<string|number|boolean>(this.cacheKeyInput.trim());this.addLog('Cache',`get("${this.cacheKeyInput}") =${val}`,'success');}

三、模式二:惰性初始化(Lazy Load)

适合计算代价较高的数据:

// 只计算一次,后续直接从缓存读取functiongetExpensiveConfig():Config{constCACHE_KEY='app_config';if(!CacheUtil.has(CACHE_KEY)){constconfig=computeExpensiveConfig();// 耗时计算CacheUtil.put<Config>(CACHE_KEY,config);}returnCacheUtil.get<Config>(CACHE_KEY);}

四、模式三:ClickUtil 防抖的依赖关系

ClickUtil的防抖实现完全依赖CacheUtil,这是工具类协作的典型示例:

// ClickUtil 内部的防抖实现staticdebounce(func:()=>void,wait:number=1000,clickId:string=ClickUtil.defaultId){// 1. 从 CacheUtil 读取上一次的 timeoutIDletcacheID=CacheUtil.get<number>(`ClickUtil_debounce_timeoutID_${clickId}`);// 2. 如果存在,清除上一次的定时器if(cacheID!==undefined&&cacheID!==null){clearTimeout(cacheID);}// 3. 设置新的定时器lettimeoutID=setTimeout(()=>{typeoffunc==='function'&&func();clearTimeout(timeoutID);},wait);// 4. 将新的 timeoutID 存入 CacheUtilCacheUtil.put<number>(`ClickUtil_debounce_timeoutID_${clickId}`,timeoutID);}

CacheUtil在这里充当了"跨调用的状态存储":每次调用debounce都是独立的函数调用,但通过CacheUtil可以访问上一次调用存储的状态。

五、模式四:防重复请求标记

constLOADING_KEY='isUserInfoLoading';asyncfunctionloadUserInfo(){// 防止重复请求if(CacheUtil.has(LOADING_KEY)&&CacheUtil.get<boolean>(LOADING_KEY)){return;}CacheUtil.put<boolean>(LOADING_KEY,true);try{constuser=awaitfetchUserInfo();CacheUtil.put<UserInfo>('userInfo',user);}finally{CacheUtil.remove(LOADING_KEY);// 无论成功失败都要清除标记}}

六、模式五:退出登录时清理

用户退出登录时,需要清理所有与用户相关的缓存:

functiononLogout(){// 方式一:逐个删除已知的 keyCacheUtil.remove('userToken');CacheUtil.remove('userInfo');CacheUtil.remove('userPermissions');// 方式二:一键清空全部(适合缓存全为用户数据的场景)CacheUtil.clear();// 方式三:只清除业务缓存,保留工具缓存// 这时需要约定好 key 的命名规范}

在 Demo 中,点击"清空全部缓存"按钮就演示了clear()的效果:

cacheClearAll(){CacheUtil.clear();this.addLog('Cache','clear() 所有缓存已清空','success');this.refreshCacheList();}

七、缓存 UI 展示

Demo 中展示了如何实时展示缓存内容:

// 缓存列表展示Column(){Text('缓存内容').fontSize(13).fontColor('#666').fontWeight(FontWeight.Medium).alignSelf(ItemAlign.Start).margin({bottom:8})if(this.cacheEntries.length===0){Text('暂无缓存数据').fontSize(12).fontColor('#CCC').width('100%').textAlign(TextAlign.Center).padding({top:16,bottom:16})}else{ForEach(this.cacheEntries,(e:CacheEntry)=>{Row(){Text(e.key).fontSize(12).fontColor('#D63384').fontFamily('monospace').layoutWeight(0.8).maxLines(1)Text(`:${e.value}`).fontSize(12).fontColor('#555').layoutWeight(1.2).maxLines(1)Text(e.type).fontSize(10).fontColor('#888')}.width('100%').padding({top:6,bottom:6})},(e:CacheEntry)=>e.key)}}

八、CacheUtil 的局限性

特性CacheUtil替代方案
持久化❌ 重启丢失PreferencesUtil(用户首选项)
加密存储❌ 明文AssetUtil(关键资产)
容量限制受内存限制数据库或文件
类型安全弱(需手动 as)使用 TypeScript 接口
跨进程共享共享偏好设置

九、命名规范建议

使用CacheUtil时,key 命名建议遵循以下规范,避免冲突:

// 使用模块前缀'user_token'// 用户模块'config_theme'// 配置模块'click_debounce_xxx'// ClickUtil 内部用(已有命名规范)// 避免过于简单的 key'token'// 容易与其他地方冲突'data'// 完全不知道存的是什么

十、小结

CacheUtil虽然只有 6 个方法,但通过不同的使用模式,可以解决:

  1. 安全读取has()+get()组合
  2. 惰性初始化:避免重复计算
  3. 工具协作:为ClickUtil等提供状态存储
  4. 防重复操作:标记进行中的异步操作
  5. 批量清理:登出时clear()一键清空

理解CacheUtil的设计,也有助于理解整个 HoUtils 工具集内部的依赖关系。

http://www.zskr.cn/news/1362538.html

相关文章:

  • 别再乱码了!一文搞懂Windows记事本里ANSI、GBK、SJIS这些编码到底怎么选
  • 2026技术分享:企业海外投资需要哪些部门审批/公司成立一年可以对外投资吗/出生证明海牙认证/北京企业境外投资/选择指南 - 优质品牌商家
  • 别再只调参了!用SAO算法优化你的神经网络超参数(附PyTorch示例)
  • 2026年靠谱的绵阳整装全屋定制高性价比公司 - 品牌宣传支持者
  • 05华夏之光永存:28nm耐高温抗辐射可靠性专项优化|国产制程车规工业级对标3nm环境耐受性方案
  • 【2024最严合规落地清单】:金融/医疗/政务三大强监管行业AI Agent设计红线与审计通关模板
  • 别再只盯着MSE了!用Python实战对比5大回归评估指标(附避坑指南)
  • 别再死记硬背了!用Python实战案例帮你彻底搞懂假设检验(附代码与避坑指南)
  • 深圳企业如何在AI搜索浪潮中抢占认知高地:GEO优化实战路径与服务商选型指南 - GEO优化
  • 虚拟粒子与机器学习:提升粗粒化分子模拟精度的新方法
  • Vision Mamba边缘硬件加速器设计:从线性SSM原理到端到端架构实现
  • HarmonyOS BgTaskUtil 后台任务生命周期与错误处理最佳实践
  • HarmonyOS BgTaskUtil 后台长时任务入门:让 App 在后台持续运行
  • 别再硬改Seurat对象行名了!从ENSG到Gene Symbol,我的完整避坑与重建流程
  • 保姆级教程:用Python脚本将COCO人体关键点数据集转为YOLOv5/YOLOv8训练格式
  • 昇腾CANN ATB KV Cache 与 PagedAttention:显存碎片消除的完整方案
  • AI Agent测试失效导致客户投诉暴增300%?揭秘某头部银行智能投顾系统上线72小时崩塌的全链路根因分析
  • 仅限首批200家零售企业获取:2024中国零售Agent成熟度评估矩阵V2.1(含137项能力测评项+自动生成差距报告)
  • 【教育智能化临界点预警】:再不掌握AI Agent教学编排逻辑,3个月内将被首批智能助教替代
  • Claude学术写作辅助应用:3天写出SCI初稿?实测7个被顶刊编辑默许的Prompt技巧
  • 保姆级教程:为你的Avalonia(.NET6)应用制作银河麒麟V10专属deb安装包(含字体修复)
  • 解决KEIL C166调试器与引导加载程序配置错误
  • ScaleRTL:基于大语言模型的Verilog代码生成技术解析
  • 别再复制粘贴了!Ubuntu 22.04 LTS上手动编译OpenFOAM v2206的保姆级避坑指南
  • 从零搭建一个AI应用:用Python+Milvus快速构建你的第一个图像检索系统
  • 图滤波器:从信号处理到机器学习的核心工具与应用实践
  • 特征工程与特征选择
  • 我的毕业设计:用SVM给微博评论‘看相’,从爬虫到部署的踩坑实录
  • ERR_CONNECTION_REFUSED 根本原因与四步定位法
  • CentOS 7上解决soffice转换doc到docx报错‘no export filter‘的完整指南(附字体安装)