【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则在处理复杂耗时任务时表现出色。根据实际需求,选择最适合的方案,能有效提升开发效率和用户体验。希望本文对您在异步操作的选择和使用上有所帮助。

相关推荐
轻口味6 分钟前
【每日学点鸿蒙知识】沙箱目录、图片压缩、characteristicsArray、gm-crypto 国密加解密、通知权限
pytorch·华为·harmonyos
xo198820114 小时前
鸿蒙人脸识别
redis·华为·harmonyos
塞尔维亚大汉5 小时前
【OpenHarmony】 鸿蒙 UI开发之CircleIndicator
harmonyos·arkui
BisonLiu5 小时前
华为仓颉鸿蒙HarmonyOS NEXT仓颉原生数据网络HTTP请求(ohos.net.http)
harmonyos
BisonLiu5 小时前
华为仓颉鸿蒙NEXT原生加解密算法库框架
harmonyos
变色龙云5 小时前
网页生成鸿蒙App
华为·harmonyos
BisonLiu5 小时前
华为仓颉鸿蒙HarmonyOS NEXT仓颉原生ohos.request(上传下载)
harmonyos
s_daqing5 小时前
华为手机鸿蒙4.2连接不上adb
华为·智能手机·harmonyos
Lucky me.5 小时前
鸿蒙开发使用axios请求后端网络服务出现该错误
华为·harmonyos
_Shirley5 小时前
鸿蒙设置app更新跳转华为市场
android·华为·kotlin·harmonyos·鸿蒙