【HarmonyOS】TaskPool非阻塞UI

TaskPool方法不会阻塞UI,如果做上传图片的功能加载Loading记得使用TaskPool,Promise、Async/Await都会阻塞UI

【引言】

发现Promise可能会阻塞UI,尝试使用async或await,但发现它们仍然会导致阻塞。后来看到chaoxiaoshu回复的TaskPool方法,发现使用该方法后UI不再阻塞。因此,我特意编写了一个加载弹窗进行测试,结果同样显示,只有TaskPool方法不会阻塞UI。

【代码示例】

javascript 复制代码
import { taskpool } from '@kit.ArkTS';

@Component
export struct MyDialog_1 {
  @Prop dialogID: string
  @State title: string = '加载中...'

  build() {
    Stack() {
      Column() {
        LoadingProgress()
          .color(Color.White).width(100).height(100)
        Text(this.title)
          .fontSize(18).fontColor(0xffffff).margin({ top: 8 })
          .visibility(this.title ? Visibility.Visible : Visibility.None)
      }
    }
    .onClick(() => {
      getContext(this).eventHub.emit(this.dialogID, "关闭弹窗")
    })
    .width(180)
    .height(180)
    .backgroundColor(0x88000000)
    .borderRadius(10)
    .shadow({
      radius: 10,
      color: Color.Gray,
      offsetX: 3,
      offsetY: 3
    })
  }
}

@Entry
@Component
struct Page28 {
  @State time3: string = ""
  @State isShowLoading: boolean = false

  build() {
    Stack() {
      Column({ space: 20 }) {
        Button("【方案一】测试Promise")
          .type(ButtonType.Capsule)
          .onClick(() => {
            this.isShowLoading = true
            this.time3 = 'loading...'
            console.log("start call promise")
            testPromise(100000000).then((time) => {
              this.time3 = `耗时:${time}`
              console.log("promise then")
              this.isShowLoading = false
            })
            console.log("end call promise")
          })

        Button("【方案二】测试async await")
          .type(ButtonType.Capsule)
          .onClick(() => {
            this.isShowLoading = true
            this.time3 = 'loading...'
            console.log("start call promise")
            this.testPromise()
            console.log("end call promise")
          })
        Button("【方案三】测试taskpool")
          .type(ButtonType.Capsule)
          .onClick(() => {
            this.isShowLoading = true
            this.time3 = 'loading...'
            let task: taskpool.Task = new taskpool.Task(concurrentFunc, 100000000);
            taskpool.execute(task);
            task.onReceiveData((time: number) => {
              this.time3 = `耗时:${time}`;
              console.log("====end")
              this.isShowLoading = false
            })
          })
        Text(this.time3)
      }.alignItems(HorizontalAlign.Start)

      MyDialog_1().visibility(this.isShowLoading ? Visibility.Visible : Visibility.None)
    }.width('100%').height('100%')

  }

  //耗时操作
  async testPromise() {
    let time = await testPromise(100000000)
    time = new Date().getTime() - time
    this.time3 = `耗时:${time}毫秒`
    console.log("promise then")
    this.isShowLoading = false
  }
}

function testPromise(count: number): Promise<number> {
  return new Promise<number>((resolve) => {
    let time = Date.now().valueOf()
    let num = 0
    for (let i = 0; i < count; i++) {
      +num
    }
    time = Date.now().valueOf() - time
    resolve(time)
  })
}

@Concurrent
function concurrentFunc(count: number): void {
  let time = Date.now().valueOf()
  let num = 0
  for (let i = 0; i < count; i++) {
    +num
  }
  time = Date.now().valueOf() - time
  taskpool.Task.sendData(time);
}

【方案一:Promise】

优点:

易于理解:Promise的语法简单,易于理解和使用。

链式调用:可以通过.then进行链式调用,处理多个异步操作。

缺点:

阻塞UI:在执行耗时任务时,Promise会阻塞UI线程,导致Loading弹窗不能及时显示。

【方案二:Async/Await】

优点:

同步写法:Async/Await 使异步代码看起来像同步代码,更加直观。

错误处理:可以使用try/catch块处理错误,使代码更加清晰。

缺点:

阻塞UI:与Promise类似,Async/Await在执行耗时任务时仍会阻塞UI线程,导致Loading弹窗不能及时显示。

【方案三:TaskPool】

优点:

真正的异步:TaskPool可以将耗时任务放到独立的线程中执行,不会阻塞UI线程,保证了UI的流畅性。

数据通信:通过task.onReceiveData可以方便地接收任务结果。

缺点:

复杂度增加:引入了多线程处理,增加了代码的复杂度和维护成本。

【使用注意事项】

任务复杂度:

如果任务较为简单且不会长时间阻塞UI,可以考虑使用Promise或Async/Await。

如果任务较为复杂且耗时较长,建议使用TaskPool以保证UI的流畅性(例如,上传图片时显示加载中)。

代码可读性:

Promise和Async/Await的语法较为简单,适合初学者使用。

TaskPool需要对多线程有一定了解,适合有经验的开发者。

性能考虑:

TaskPool在处理大量或耗时任务时表现更优,可以显著提升应用性能。

Promise和Async/Await在小任务场景下更简洁高效。

【总结】

选择合适的异步操作方案至关重要。Promise和Async/Await适合处理简单的异步任务,而TaskPool则在处理复杂耗时任务时表现出色。根据实际需求,选择最适合的方案,能有效提升开发效率和用户体验。希望本文对您在异步操作的选择和使用上有所帮助。

相关推荐
阿图灵1 小时前
Agentic AI 架构入门(九):Agent 通信协议全景——ACP/A2A/AG-UI/MCP
人工智能·ui·架构·ai agent·智能体·mcp·agentic ai
梦想不只是梦与想1 小时前
鸿蒙 测试工具:DevEco Testing(一)
测试工具·harmonyos·testing
大锅盖14 小时前
Web 工单要调用相机,第一步不是打开取景框,而是建立能力门禁
前端·数码相机·harmonyos
AI分享猿6 小时前
UI设计Prompt系列(十二):设计系统入门——把视觉语言沉淀为可复用规范
ui·prompt
l1m0_6 小时前
告别反复修改Prompt:AI生成React应用并落地开发的实战复盘
前端·react.js·ui·ai·设计
大千UI工场8 小时前
时序数据库对数字孪生的作用
数据库·ui·时序数据库·前端开发·b端管理系统
贾伟康8 小时前
【华夏二十四节气|07】HarmonyOS 6.0.2(22) ArkTS 节气搜索实战:多字段匹配与四态闭环
移动开发·harmonyos·arkts·arkui·本地搜索
大龄秃头程序员9 小时前
Flutter 项目鸿蒙适配实战:从环境搭建到多环境打包全指南
harmonyos
贾伟康10 小时前
【万能转换器|18】HarmonyOS ArkTS 权限与隐私实战:让 module.json5、功能说明和拒绝路径一致
移动开发·harmonyos·arkts·权限管理·隐私合规
贾伟康10 小时前
【万能转换器|19】HarmonyOS ArkTS 回归测试实战:覆盖启动、空数据、异常输入和重复点击
软件测试·移动开发·harmonyos·arkts·回归测试