📚 鸿蒙进阶专栏 · 第 15 篇 / 共 20 篇(进阶篇 11-20)
上一篇:Navigation 导航体系 | 下一篇:项目分层架构:MVC 到三层再到模块化

目录

异步并发:async/await 与 Promise 正确姿势

一、先理解:UI 是单线程的

二、Promise 三态与 async/await

三、并发:多个请求怎么发最快

四、真正的重活:TaskPool

五、自查清单

六、下一篇预告


 

异步并发:async/await 与 Promise 正确姿势

为什么你的 App 会卡?十有八九是把耗时任务放错了地方。这篇讲清鸿蒙的单线程模型,以及异步代码的标准写法。

一、先理解:UI 是单线程的

所有 build() 渲染、点击事件都跑在主线程。主线程被占用超过 100ms,用户就能感到卡顿。所以网络、数据库、大文件读写,都必须异步。

二、Promise 三态与 async/await

// 鸿蒙 API 大量返回 Promise,标准处理姿势:
async loadData(): Promise<void> {
  this.loading = true
  try {
    const res = await http.createHttp().request(URL)
    this.list = this.parse(res)
  } catch (e) {
    this.toast('网络异常,请重试')     // 必须 catch!
  } finally {
    this.loading = false               // 无论成败都关 loading
  }
}

三、并发:多个请求怎么发最快

// ❌ 串行:总耗时 = a + b + c
const a = await getBanner()
const b = await getGoods()
const c = await getUser()

// √ 并行:总耗时 = max(a, b, c)
const [a2, b2, c2] = await Promise.all([
  getBanner(), getGoods(), getUser()
])

四、真正的重活:TaskPool

await 只是「不阻塞等待」,计算本身还在主线程。如果要做图片批量压缩、JSON 大解析、加密运算这类 CPU 密集任务,用 TaskPool 把活派给子线程:

import { taskpool } from '@kit.ArkTS'

@Concurrent
function heavyCompute(data: ArrayBuffer): number {
  // 在子线程执行的重计算
  return data.byteLength
}

// 调用
const result = await taskpool.execute(
  new taskpool.Task(heavyCompute, buffer))
⚠️ @Concurrent 函数要求参数可序列化、不能引用外部 this。传函数对象、跨线程 DOM 之类的心智模型不适用,遵守「传数据进去、拿结果回来」。

五、自查清单

症状根因药方
点击后界面冻结同步等待耗时操作改成 async/await
加载完成前白屏没有 loading 状态加 LoadingProgress
列表滚动掉帧主线程做计算TaskPool 派发
异常导致卡在 loading没写 finallyloading 置位放 finally

六、下一篇预告

异步解决了「卡」,但代码组织还是一锅粥。下一篇:三层架构,让项目结构能支撑真正规模的 App。


进阶系列持续更新中,点赞 + 收藏 + 关注不迷路。
遇到问题评论区贴报错信息 + 关键代码,看到都会回。也欢迎留言点播你想看的进阶主题。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐