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

【引言】
发现Promise可能会阻塞UI,尝试使用async或await,但发现它们仍然会导致阻塞。后来看到chaoxiaoshu回复的TaskPool方法,发现使用该方法后UI不再阻塞。因此,我特意编写了一个加载弹窗进行测试,结果同样显示,只有TaskPool方法不会阻塞UI。
【代码示例】
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则在处理复杂耗时任务时表现出色。根据实际需求,选择最适合的方案,能有效提升开发效率和用户体验。希望本文对您在异步操作的选择和使用上有所帮助。
更多关于HarmonyOS 鸿蒙Next TaskPool方法不会阻塞UI,如果做上传图片的功能加载Loading记得使用TaskPool,Promise、Async/Await都会阻塞UI的实战教程也可以访问 https://www.itying.com/category-93-b0.html
异步是主线程异步,这概念得区分主线程和其他线程,其他线程也可以用异步处理。两个概念
更多关于HarmonyOS 鸿蒙Next TaskPool方法不会阻塞UI,如果做上传图片的功能加载Loading记得使用TaskPool,Promise、Async/Await都会阻塞UI的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
taskpool + 通信,
基本信息
- **任务池类型**: 动态任务池
- **当前状态**: 激活
- **创建时间**: 2023-03-15
- **到期时间**: 2023-04-15
- **负责人**: 张三
- **描述**: 这是一个用于处理通信相关任务的任务池。
🌹
在HarmonyOS鸿蒙系统中,为了确保UI线程不被阻塞,特别是在执行如上传图片这类耗时操作时,应当合理使用Next TaskPool。TaskPool是鸿蒙系统提供的一种异步任务执行机制,它允许将耗时操作放在后台线程执行,从而保持UI线程的流畅性。
对于提到的上传图片功能,如果使用Promise、Async/Await等同步等待结果的编程方式,确实可能会导致UI线程阻塞,因为这些方式在本质上是在等待异步操作完成,而等待过程是在UI线程上进行的。为了避免这种情况,应当将这些耗时操作放入TaskPool中执行。
具体实现时,可以通过鸿蒙提供的API将上传图片的任务提交给TaskPool。TaskPool会负责在后台线程中执行该任务,并在任务完成后通过回调函数或其他机制通知UI线程。这样,即使上传图片操作耗时较长,也不会影响到UI的响应性和流畅度。
示例代码(伪代码):
// 假设有一个上传图片的函数uploadImage
void uploadImageAsync() {
TaskPool::Execute([=]() {
// 在这里执行上传图片的操作
// 上传完成后,可以通过回调或其他方式通知UI线程
});
}
如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html

