HarmonyOS CacheUtil 进阶:缓存设计模式与典型应用场景
2026/5/24 2:10:34 网站建设 项目流程

文章目录

    • 背景
    • 一、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 工具集内部的依赖关系。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询