第 17 课2026.07.27
适用场景:页面进入后请求网络数据、读取数据库或执行其他需要等待的任务
第 17 课:异步数据加载与页面状态
- 日期:2026-07-27
- 知识点:
async/await、加载状态、成功结果与错误信息 - 适用场景:页面进入后请求网络数据、读取数据库或执行其他需要等待的任务
承接上一课的组件生命周期:上一课确定了“何时开始加载”;本课继续学习“异步任务完成后,如何用明确的数据状态驱动页面”。
1. 核心概念:用状态表达加载结果
异步加载通常有三种结果:
text
开始加载 -> loading = true
加载成功 -> 写入数据
加载失败 -> 写入错误信息
任务结束 -> loading = falseasync 函数会返回 Promise,await 用来等待异步结果。页面只根据 loading、items 和 errorMessage 渲染,不在 UI 层伪造加载结果。
2. 最小示例
ts
@Entry
@Component
struct MessagePage {
@State loading: boolean = false;
@State items: string[] = [];
@State errorMessage: string = '';
aboutToAppear(): void {
this.loadMessages();
}
async loadMessages(): Promise<void> {
this.loading = true;
this.errorMessage = '';
try {
this.items = await this.queryMessages();
} catch (error) {
this.errorMessage = '加载失败,请重试';
} finally {
this.loading = false;
}
}
queryMessages(): Promise<string[]> {
return Promise.resolve(['系统通知', '学习提醒']);
}
build() {
Column({ space: 12 }) {
if (this.loading) {
Text('加载中...')
} else if (this.errorMessage.length > 0) {
Text(this.errorMessage)
.fontColor(Color.Red)
} else {
ForEach(this.items, (item: string) => {
Text(item)
}, (item: string) => item)
}
}
.width('100%')
.padding(20)
}
}try 处理成功结果,catch 记录失败结果,finally 保证无论成功还是失败都会结束加载状态。实际项目中,把 queryMessages() 替换为真实的数据层调用即可。
3~5 分钟练习
给示例增加一个“重新加载”按钮:
- 点击按钮时再次调用
loadMessages()。 - 正在加载时禁用按钮。
- 按钮文字在加载时显示“加载中”,其余时间显示“重新加载”。
参考答案
在 build() 的 Column 中追加:
ts
Button(this.loading ? '加载中' : '重新加载')
.enabled(!this.loading)
.onClick(() => {
this.loadMessages();
})按钮只触发数据加载;是否可点击和显示什么文字,都直接由 loading 状态决定。
与上一课的联系
上一课使用 aboutToAppear() 确定组件进入时启动任务,并强调离开时释放长期资源;本课把一次异步数据加载接到这个生命周期点上,再用明确的加载、成功和失败状态驱动 UI。下一步可以继续学习如何把页面请求逻辑下沉到独立的数据服务中。