news 2026/6/10 11:03:58

鸿蒙异步并发 async/await 最佳实践,代码瞬间优雅

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙异步并发 async/await 最佳实践,代码瞬间优雅

Hello,兄弟们,我是 V 哥!

还记得以前写 Android 或者早期 JavaScript 的时候,那个传说中的**“回调地狱”**吗?

// 伪代码演示:让人崩溃的金字塔login(user,(res1)=>{getUserInfo(res1.id,(res2)=>{getOrders(res2.token,(res3)=>{getDetail(res3.orderId,(res4)=>{// 终于结束了... 代码已经缩进到屏幕外边了})})})})

这种代码,维护起来简直是噩梦!但在鸿蒙 ArkTS 的 API 21 环境下,兄弟们千万别再这么写了!ArkTS 是基于 TypeScript 的,它原生支持非常强大的async/await语法。

今天 V 哥就带你把这段“金字塔”拍平,用同步的逻辑写异步的代码,优雅得像喝下午茶一样!


核心心法:把“等待”变成“暂停”

兄弟们,记住 V 哥这两个口诀:

  1. async:加在函数定义前面,表示“这里面有耗时的活儿”。
  2. await:加在耗时的调用前面,表示“等着这儿干完,再去干下一行,但别把界面卡死”。

有了这两个神器,异步代码写出来就像在写小学作文,从上到下,一行一行读,逻辑清晰无比。


实战代码案例

为了让大家直观感受,V 哥写了一个完整的 Demo。咱们模拟三个常见的真实场景:

  1. 串行执行:先登录,再拿用户信息。
  2. 并发执行:同时拉取“广告配置”和“首页推荐”。
  3. 异常处理:优雅地捕获网络错误。

操作步骤:打开你的 DevEco Studio 6.0,新建一个 ArkTS 页面,把下面的代码完整复制进去,直接运行!

importpromptActionfrom'@ohos.promptAction';/** * V哥的模拟网络请求类 * 在真实项目中,这里会换成 httpRequest 或者 网络库 */classNetworkSimulator{// 模拟一个异步耗时操作,返回 Promisestaticrequest(apiName:string,data:string,delay:number):Promise<string>{returnnewPromise((resolve,reject)=>{setTimeout(()=>{// 模拟 20% 的概率失败if(Math.random()<0.2){reject(newError(`${apiName}请求失败,网络不给力!`));}else{resolve(`${apiName}返回的数据:${data}`);}},delay);});}}@Entry@Componentstruct AsyncAwaitDemo{@StateresultLog:string='V哥准备好输出日志了...';@StateisLoading:boolean=false;build(){Column(){Text('鸿蒙 async/await 实战实验室').fontSize(24).fontWeight(FontWeight.Bold).margin({top:30,bottom:20})// 场景一:串行执行Button('场景1:串行执行 (登录 -> 获取信息)').width('90%').margin({bottom:15}).onClick(()=>{this.testSequential();})// 场景二:并发执行Button('场景2:并发执行 (同时拉取配置和广告)').width('90%').margin({bottom:15}).onClick(()=>{this.testParallel();})// 场景三:异常捕获Button('场景3:异常捕获 (模拟失败重试)').width('90%').margin({bottom:15}).onClick(()=>{this.testErrorHandling();})// 日志显示区域Column(){Text(this.resultLog).fontSize(14).fontColor('#333333').width('100%')}.width('90%').height('40%').padding(15).backgroundColor('#F1F3F5').borderRadius(10).margin({top:20})if(this.isLoading){LoadingProgress().width(30).height(30).margin({top:20}).color(Color.Blue)}}.width('100%').height('100%').padding({left:20,right:20})}/** * V哥解析:场景1 - 串行执行 * 特点:一步接一步,下一步依赖上一步的结果。 * 代码逻辑:完全是线性的,像同步代码一样易读! */asynctestSequential(){this.isLoading=true;this.resultLog='1. 开始登录...\n';try{// V哥重点:await 会暂停函数执行,直到 Promise resolve// 这里模拟先登录,耗时 1000msletloginRes=awaitNetworkSimulator.request('LoginAPI','Token123',1000);this.resultLog+=`${loginRes}\n`;this.resultLog+='2. 正在获取用户信息...\n';// 依赖上面的 Token,继续 awaitletuserRes=awaitNetworkSimulator.request('GetUserInfo','V哥的大名',800);this.resultLog+=`${userRes}\n`;this.resultLog+='✅ 全部完成!(串行总耗时约 1.8s)';promptAction.showToast({message:'串行执行完成'});}catch(error){this.resultLog+=`❌ 出错了:${error.message}`;}finally{this.isLoading=false;}}/** * V哥解析:场景2 - 并发执行 * 特点:两个请求互不依赖,同时发出,谁先回来谁先结束。 * 优势:速度最快!总耗时 = 两个请求中最慢的那个,而不是两者之和。 */asynctestParallel(){this.isLoading=true;this.resultLog='1. 同时启动多个任务...\n';// 记录开始时间conststartTime=Date.now();try{// V哥重点:Promise.all()// 把所有要并发的 Promise 放进数组里// await 会等数组里所有的 Promise 都 resolve 才继续letresults=awaitPromise.all([NetworkSimulator.request('GetConfig','系统配置',1500),// 假设这个慢NetworkSimulator.request('GetBanner','广告图片',1000)// 假设这个快]);// results 是一个数组,顺序和你传入的顺序一致,不管谁先回来this.resultLog+=`${results[0]}\n`;// 第一个结果this.resultLog+=`${results[1]}\n`;// 第二个结果constduration=Date.now()-startTime;this.resultLog+=`✅ 全部完成!(并发总耗时约${duration}ms,比串行快!)`;promptAction.showToast({message:'并发执行完成'});}catch(error){this.resultLog+=`❌ 出错了:${error.message}`;}finally{this.isLoading=false;}}/** * V哥解析:场景3 - 异常处理 * 特点:async/await 下,我们用 try...catch...finally 代替 .then().catch() * 这比传统的 Promise 链式调用要直观得多,像处理 Java 异常一样舒服。 */asynctestErrorHandling(){this.isLoading=true;this.resultLog='尝试发送请求 (模拟20%失败率)...\n';try{// 这里的请求可能会抛出 Errorletdata=awaitNetworkSimulator.request('RiskyAPI','试试运气',1000);this.resultLog+=`成功:${data}`;promptAction.showToast({message:'请求成功'});}catch(error){// V哥重点:一旦任何一步 await 报错,直接跳进 catchthis.resultLog+=`捕获到异常:${error.message}\n`;this.resultLog+=`这里可以进行重试逻辑...`;promptAction.showToast({message:'请求被拦截'});}finally{// V哥重点:finally 无论成功失败都会执行// 适合用来关闭 Loading 弹窗this.isLoading=false;}}}

运行结果:


V 哥的代码深度解析

兄弟们,代码能跑了,咱们得懂原理,不然面试的时候要挂!

1. 为什么 async/await 不会卡死界面?

这就是并发编程的魔力。
当你写let res = await someRequest()的时候,ArkTS 的运行时会把当前任务的挂起,把主线程的控制权交还给 UI 系统。
这就好比你去排队买奶茶,你叫服务员做奶茶(发起请求),你站在旁边等(await),但**店里的其他人(UI线程)**依然可以继续进店买东西。只有当你的奶茶好了(Promise resolve),你才拿着奶茶走人(代码继续往下走)。

2. Promise.all 是性能优化的利器

在场景 2 中,V 哥演示了Promise.all
如果你的首页有 5 个接口,互不依赖,你千万别写 5 行 await:

// ❌ 错误写法:慢得要死leta=awaitreq1();// 等1秒letb=awaitreq2();// 再等1秒// ... 总耗时 5秒
// ✅ V 哥正确写法:飞快letresults=awaitPromise.all([req1(),req2(),req3(),req4(),req5()]);// 总耗时 = 最慢的那个接口 (假设是 1.2秒)

这可是实打实的性能提升,用户打开 App 的速度直接肉眼可见变快!

3. 不要忘记了 try-catch

以前写 Promise 链,如果不加.catch(),报错了可能就像石沉大海,静默失败。
用了async/await一定要包裹在try...catch里。这是对自己代码负责,也是对用户负责。


总结

在 DevEco Studio 6.0 里,这套组合拳用熟练了,你的代码质量和开发效率绝对能甩开同行一条街,V 哥稍微小结一下:

  1. 逻辑复杂?async/await拍平金字塔。
  2. 请求多且慢?Promise.all并行加速。
  3. 怕出错?try/catch稳稳兜底。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/7 10:41:03

DataCMD 怎么部署?用服务器搭建终端数据可视化工具

如果你日常做运维、管服务器,肯定对下面这些场景非常熟悉: 🖥️ top、htop、df -h、iostat 来回敲 😵 数据是有了,但全是文本,靠自己脑补趋势 📉 CPU/负载突然飙高,只能事后翻日志 🧠 想把常用指标“看成图”,却又不想上复杂监控系统 后来我开始用 DataCMD 这种…

作者头像 李华
网站建设 2026/6/9 13:17:11

二分+滑窗|hash

lc2982二分定窗class Solution { public:int maximumLength(string s) {auto check [&](int mid)->bool {unordered_map<char, int> fre_map;for (int i 0; i < s.length();) {int l i;char c s[i];int fre 0;while (s[i] c) {i;}if (i - l > mid) {f…

作者头像 李华
网站建设 2026/6/4 14:37:25

使用 frp 实现内网穿透:让本地服务器安全暴露到公网

使用 frp 实现内网穿透&#xff1a;让本地服务器安全暴露到公网 frp&#xff08;frp 是 Fast Reverse Proxy 的缩写&#xff09;是一个轻量、高效的内网穿透工具&#xff0c;可以将内网的 SSH、Web、MySQL 等服务安全地暴露到公网。本文基于一个实际生产环境&#xff0c;介绍 …

作者头像 李华
网站建设 2026/5/30 23:12:19

沃虎电子BMS隔离通讯变压器:新能源领域的安全通信核心

在电池管理系统&#xff08;BMS&#xff09;中&#xff0c;隔离通讯变压器是保障高低压电路安全隔离、信号稳定传输的关键器件&#xff0c;直接决定电池系统的安全性、可靠性与使用寿命。沃虎电子深耕磁性器件研发&#xff0c;推出的BMS隔离通讯变压器系列&#xff0c;以高隔离…

作者头像 李华
网站建设 2026/6/10 0:24:38

MySQL数据可视化实战:从查询到图表的全流程

数据可视化是将枯燥的数据库数据转化为直观图表的核心手段&#xff0c;而 MySQL 作为最常用的关系型数据库&#xff0c;并非只能做数据存储和查询 —— 结合合理的查询技巧与可视化工具&#xff0c;你可以用 MySQL 快速实现从 “数据提取” 到 “图表展示” 的全链路可视化分析…

作者头像 李华
网站建设 2026/5/31 1:11:45

AI营销内容如何将成本锐减90%?2026企业终极指南

原圈科技 营销洞察原圈科技的AI营销内容解决方案,旨在解决企业高成本与低效率痛点。本文通过四步实操指南,详解如何利用多智能体系统实现内容成本降低90%、效率数倍提升,助您构建坚不可摧的品牌护城河。引言欢迎来到2026年。在今天的商业世界里,AI内容生成不再是遥远的趋势,而…

作者头像 李华