当前位置: 首页 > 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.jsqmd.com/news/874552/

相关文章:

  • 2026成都菲斯曼维修靠谱厂家推荐:菲斯曼壁挂炉全国售后电话/菲斯曼壁挂炉全国统一售后电话/菲斯曼壁挂炉出现F02/选择指南 - 优质品牌商家
  • ArcGIS Pro 3.7 重磅升级!这四大模块更新,让GIS效率翻倍
  • 别再只用最小二乘法了!用Python+OpenCV搞定RANSAC直线拟合(附代码对比)
  • HarmonyOS CacheUtil 内存缓存工具:6 个方法让你告别重复计算
  • 2026技术分享:企业海外投资需要哪些部门审批/公司成立一年可以对外投资吗/出生证明海牙认证/北京企业境外投资/选择指南 - 优质品牌商家
  • 别再只调参了!用SAO算法优化你的神经网络超参数(附PyTorch示例)
  • 如果知识库有 1000 万份文档,RAG 系统如何设计?
  • 2026年靠谱的绵阳整装全屋定制高性价比公司 - 品牌宣传支持者
  • HarmonyOS ArkTS CacheUtil 内存缓存实战场景全解析
  • 【Java后端开发】花了2k+多的人民币,烧了几十亿Token,慢慢整理出来适用于Java开发人员的codex配置,还在持续优化中
  • 3步快速上手SSDD:合成孔径雷达舰船检测终极指南
  • 深圳企业如何在AI搜索浪潮中抢占认知高地:GEO优化实战路径与服务商选型指南 - GEO优化
  • C51编译器局部变量存储优化与寄存器分配解析
  • SqueezeBERT:借CV分组卷积为NLP模型瘦身,实现移动端4.3倍加速
  • 大模型知识大观:从数学基础到应用落地的完整图谱
  • 3步解锁Windows远程桌面多人连接:RDP Wrapper Library完整指南
  • 2026长三角正规月嫂培训优质机构推荐榜:哈柏母婴职业教育、哈柏培训学校、哈柏母婴培训学校、哈柏母婴职业技能培训学校选择指南 - 优质品牌商家
  • 如何让 RAG 支持跨语言查询(如中文问题检索英文文档)?
  • C#中Jobject转string方法实现
  • YOLACT实战:从训练到部署,让你的模型在图片和视频上实时跑起来(Python/OpenCV)
  • 链表数据结构预取技术Linkey的设计与优化
  • 保姆级教程:为你的Avalonia(.NET6)应用制作银河麒麟V10专属deb安装包(含字体修复)
  • 使用C#代码在Excel中获取工作表名称的操作指南
  • ST uPSD33xx芯片Keil断点失效问题解析与解决
  • 2026年GEO优化公司权威推荐与全意图GEO战略价值深度分析 - GEO优化
  • 电力变压器油温预测实战:如何用ETT数据集训练你的第一个LSTM模型
  • d2dx终极教程:三步让暗黑破坏神2在现代PC上焕然一新
  • 面向对象分析学习笔记:形式化方法初探与《大象——Thinking in UML》阅读心得
  • 别再复制粘贴了!Ubuntu 22.04 LTS上手动编译OpenFOAM v2206的保姆级避坑指南
  • 从零搭建私有化播客TTS流水线:Docker+TensorRT加速+实时情感注入(企业级部署手册·限免72小时)