写点什么

HarmonyOS 实战:一招解决等待多个并发结果

作者:IT小码哥
  • 2025-05-27
    北京
  • 本文字数:1584 字

    阅读完需:约 5 分钟

前言

年前公司与华为签订了合作备忘录,加入了鸿蒙生态这个大家庭。公司想赶着鸿蒙纯血系统上市之前,发布自己的鸿蒙软件。开发鸿蒙 NEXT 版本软件就变成了今年的一个工作重心。


本文主要讲解开发过程中遇到的并发问题,官方 API 11 文档写的太简单了,根本没有解决方案,小编也是苦思冥想,绞尽脑汁才找到解决方案。需要开发鸿蒙的小伙伴可以仔细阅读,避免踩坑。

问题

在开发清除缓存的功能时,鸿蒙 NEXT 提供的文档中说明,应用缓存文件有四个,需要清除指定的四个缓存文件夹。如图所示:



清除缓存代码如下:


import fs from '@ohos.file.fs'              fs.access("文件路径").then((isHas:boolean) => {      if(isHas) { //判断文件是否存在        fs.rmdirSync("文件路径")//删除文件             }    })  
复制代码


需要同时清除这四个文件夹,然后再计算这四个文件夹的大小。由于 fs.access 方法是耗时操作。所以只能在异步线程中执行。

解决方案

一般思路

鸿蒙官方文档 API 11 提供了使用 Promise 和 async/await 处理异步并发问题。



注意是单次 I/O 任务,可问题是我们需要解决同时并发问题,一次拿到四次清除缓存结果再去统计缓存大小。这个时候可能有的小伙伴就会说,那就先清除第一个,等一个结果返回再清除第二个,以此类推。也能解决问题。如下图所示:


            fs.access("文件路径1").then((isHas:boolean) => {      if(isHas) { //判断文件是否存在        fs.rmdirSync("文件路径1")//删除文件                      fs.access("文件路径2").then((isHas:boolean) => {         if(isHas) { //判断文件是否存在           fs.rmdirSync("文件路径2")//删除文件             .....................        }    })      }    })
复制代码


但是这样就会带来两个问题:多层嵌套与代码混乱。在 Flutter 中这个问题非常好解决。这里就不详细描述了。

优雅方案

使用 Promise.all 解决。小编在官方文档中并没有找到 Promise.all 相关说明,可能是鸿蒙还没注意到这种需求场景吧。直接上代码。


  1. 先将文件清除包装成一个异步任务。


asyncClear(dir: string): Promise<void> {    return new Promise((resolve, reject) => {      fs.access(dir).then((isHas: boolean) => {        if (isHas) {          fs.rmdir(dir)        }        resolve()      })    })  }
复制代码


  1. 将四个缓存文件夹对应的任务放在一个数组中。


  let promises = [      this.asyncClear("文件夹1"),      this.asyncClear("文件夹2"),      this.asyncClear("文件夹3"),      this.asyncClear("文件夹4")    ]
复制代码


  1. 将任务数组放进 Promis.all 中,等待四个任务执行结束。


 Promise.all(promises).then(() => {      // 结束回调    })
复制代码


  1. 在结束回调中 再去调用计算缓存大小的方法。


 storageStatistics.getCurrentBundleStats().then((bundleStats) => {        let cacheSizeNum = bundleStats.cacheSize        let unit = "KB"        if (cacheSizeNum > 1024) {          cacheSizeNum = Math.floor(cacheSizeNum) / 1024          unit = "KB"        }        if (cacheSizeNum > 1024) {          cacheSizeNum = Math.floor(cacheSizeNum) / 1024          unit = "MB"        }        if (cacheSizeNum > 1024) {          cacheSizeNum = Math.floor(cacheSizeNum) / 1024          unit = "GB"        }        if (cacheSizeNum > 1024) {          cacheSizeNum = Math.floor(cacheSizeNum) / 1024          unit = "TB"        }        let chacheSizeString = "" + Math.floor(cacheSizeNum) + unit      });
复制代码

总结

鸿蒙 NEXT 的 API 还不算完善,需要每个开发者的参与,发现问题,提出问题,鸿蒙开发人员才能更好的解决问题。如果您也是鸿蒙开发者,有其他更好的解决方案,欢迎评论区交流 ,互相学习,互相成长!


用户头像

IT小码哥

关注

还未添加个人签名 2021-04-29 加入

还未添加个人简介

评论

发布
暂无评论
HarmonyOS实战:一招解决等待多个并发结果_鸿蒙 Ability_IT小码哥_InfoQ写作社区