HarmonyOS 鸿蒙Next中怎样在应用中使用异步编程提高性能?
HarmonyOS 鸿蒙Next中怎样在应用中使用异步编程提高性能? 开发中需要处理异步操作问题:
- 数据库查询
- 网络请求
- 文件读写
- 多个异步操作协调
解决方案
1. 基础Promise使用
/**
* Promise基础
*/
function loadData(): Promise<Item[]> {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
];
// ✅ 成功时调用resolve
resolve(data);
// ❌ 失败时调用reject
// reject(new Error('加载失败'));
}, 1000);
});
}
// ✅ 使用Promise
loadData()
.then(data => {
console.info('加载成功:', data.length);
})
.catch(err => {
console.error('加载失败:', err);
})
.finally(() => {
console.info('加载完成');
});
2. async/await语法
/**
* async/await简化异步代码
*/
@Component
struct DataPage {
@State items: Item[] = [];
@State isLoading: boolean = false;
async aboutToAppear(): Promise<void> {
await this.loadData();
}
async loadData(): Promise<void> {
this.isLoading = true;
try {
// ✅ await等待Promise完成
const items = await ItemDao.findAll();
this.items = items;
} catch (err) {
console.error('加载失败:', err);
promptAction.showToast({ message: '加载失败' });
} finally {
this.isLoading = false;
}
}
build() {
if (this.isLoading) {
LoadingProgress();
} else {
List() {
ForEach(this.items, (item: Item) => {
ListItem() {
Text(item.name);
}
})
}
}
}
}
3. 并发执行
/**
* Promise.all: 并发执行,全部完成
*/
async function loadAllData(): Promise<void> {
try {
// ✅ 并发执行3个请求
const [items, categories, tags] = await Promise.all([
ItemDao.findAll(),
CategoryDao.findAll(),
TagDao.findAll()
]);
console.info('全部加载完成');
console.info('物品数量:', items.length);
console.info('分类数量:', categories.length);
console.info('标签数量:', tags.length);
} catch (err) {
// ❌ 任何一个失败都会进入catch
console.error('加载失败:', err);
}
}
/**
* Promise.allSettled: 等待全部完成(无论成功失败)
*/
async function loadDataSafely(): Promise<void> {
const results = await Promise.allSettled([
ItemDao.findAll(),
CategoryDao.findAll(),
TagDao.findAll()
]);
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.info(`第${index + 1}个请求成功:`, result.value.length);
} else {
console.error(`第${index + 1}个请求失败:`, result.reason);
}
});
}
4. 竞速执行
/**
* Promise.race: 返回最快完成的
*/
async function loadWithTimeout(): Promise<Item[]> {
// ✅ 设置5秒超时
const timeout = new Promise<Item[]>((_, reject) => {
setTimeout(() => {
reject(new Error('请求超时'));
}, 5000);
});
// ✅ 竞速:谁先完成返回谁
return await Promise.race([
ItemDao.findAll(), // 实际请求
timeout // 超时控制
]);
}
5. 顺序执行
/**
* 顺序执行多个异步操作
*/
async function sequentialOperations(): Promise<void> {
// ✅ 顺序执行
const item = await ItemDao.findById(1);
const category = await CategoryDao.findById(item.categoryId);
const tags = await TagDao.findByItemId(item.id);
console.info('物品:', item.name);
console.info('分类:', category.name);
console.info('标签:', tags.length);
}
/**
* 批量顺序执行
*/
async function batchSequential(ids: number[]): Promise<Item[]> {
const items: Item[] = [];
// ✅ for...of 顺序执行
for (const id of ids) {
const item = await ItemDao.findById(id);
items.push(item);
// 每次查询间隔100ms
await new Promise(resolve => setTimeout(resolve, 100));
}
return items;
}
6. 错误处理最佳实践
/**
* 完整的错误处理
*/
@Component
struct SafeDataPage {
@State items: Item[] = [];
@State error: string = '';
@State isLoading: boolean = false;
async loadData(): Promise<void> {
this.isLoading = true;
this.error = '';
try {
// ✅ 主要逻辑
const items = await ItemDao.findAll();
if (items.length === 0) {
throw new Error('暂无数据');
}
this.items = items;
} catch (err) {
// ✅ 错误分类处理
if (err instanceof Error) {
this.error = err.message;
} else {
this.error = '未知错误';
}
console.error('加载失败:', err);
} finally {
// ✅ 无论成功失败都执行
this.isLoading = false;
}
}
build() {
Column() {
if (this.isLoading) {
LoadingProgress();
} else if (this.error) {
Text(this.error).fontColor(Color.Red);
} else {
List() {
ForEach(this.items, (item: Item) => {
ListItem() {
Text(item.name);
}
})
}
}
}
}
}
7. 实战案例
/**
* 保存数据并更新UI
*/
@Component
struct ItemEditPage {
@State isSaving: boolean = false;
private item: Item = new Item();
async onSave(): Promise<void> {
if (this.isSaving) {
return; // 防止重复提交
}
this.isSaving = true;
try {
// ✅ 1. 验证数据
this.validateData();
// ✅ 2. 保存到数据库
const itemId = await ItemDao.insert(this.item);
// ✅ 3. 更新卡片
await FormDataService.getInstance().updateAllForms();
// ✅ 4. 提示成功
promptAction.showToast({ message: '保存成功' });
// ✅ 5. 返回上一页
router.back();
} catch (err) {
// ❌ 错误处理
let message = '保存失败';
if (err instanceof Error) {
if (err.message.includes('UNIQUE')) {
message = '名称已存在';
} else {
message = err.message;
}
}
promptAction.showToast({ message });
} finally {
this.isSaving = false;
}
}
validateData(): void {
if (!this.item.name) {
throw new Error('请输入名称');
}
if (this.item.name.length > 100) {
throw new Error('名称不能超过100字');
}
}
build() {
Column() {
Button('保存')
.enabled(!this.isSaving)
.onClick(() => {
this.onSave();
})
}
}
}
关键要点
1. Promise状态
// Pending(进行中) → Fulfilled(成功) 或 Rejected(失败)
const promise = new Promise((resolve, reject) => {
// 成功
resolve(data);
// 失败
reject(error);
});
2. async/await规则
// ✅ async函数返回Promise
async function getData(): Promise<Item[]> {
return await ItemDao.findAll();
}
// ✅ await只能在async函数中使用
async function loadData(): Promise<void> {
const data = await getData(); // ✅
}
// ❌ 错误:非async函数中使用await
function loadData(): void {
const data = await getData(); // ❌ 编译错误
}
3. 错误传播
async function a(): Promise<void> {
throw new Error('错误A');
}
async function b(): Promise<void> {
await a(); // ✅ 错误会向上传播
}
async function c(): Promise<void> {
try {
await b(); // ✅ 可以在这里捕获错误A
} catch (err) {
console.error('捕获到错误:', err);
}
}
最佳实践
1. 总是处理错误
// ✅ 推荐:使用try-catch
async function loadData(): Promise<void> {
try {
const data = await getData();
} catch (err) {
console.error(err);
}
}
// ❌ 不推荐:忽略错误
async function loadData(): Promise<void> {
const data = await getData(); // 错误会导致Promise rejected
}
2. 避免回调地狱
// ❌ 回调地狱
loadData((data) => {
processData(data, (result) => {
saveData(result, () => {
console.info('完成');
});
});
});
// ✅ 使用async/await
async function process(): Promise<void> {
const data = await loadData();
const result = await processData(data);
await saveData(result);
console.info('完成');
}
3. 合理使用并发
// ✅ 可以并发的操作
const [items, categories] = await Promise.all([
loadItems(),
loadCategories()
]);
// ❌ 必须顺序执行的操作
const user = await loadUser();
const profile = await loadProfile(user.id); // 依赖user
性能对比
| 场景 | 顺序执行 | 并发执行 |
|---|---|---|
| 3个独立请求 | 3s | 1s |
| 5个独立请求 | 5s | 1s |
| 性能提升 | - | 80%+ |
总结
异步编程要点:
✅ 使用async/await简化代码 ✅ Promise.all并发执行 ✅ try-catch处理错误 ✅ finally清理资源 ✅ 避免阻塞主线程
掌握异步编程,代码更简洁高效
更多关于HarmonyOS 鸿蒙Next中怎样在应用中使用异步编程提高性能?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,使用异步编程提高性能主要通过TaskPool和Worker模块实现。TaskPool适用于轻量级任务,支持任务派发和结果返回。Worker用于耗时操作,在独立线程中运行以避免阻塞主线程。开发者可使用Promise或async/await语法处理异步操作,确保UI流畅。例如,通过TaskPool执行计算密集型任务,或利用Worker处理网络请求和文件读写。
在HarmonyOS Next中,使用异步编程提升应用性能的核心是充分利用其基于ArkTS/ArkUI的并发模型,避免阻塞UI线程。主要手段包括使用Promise、async/await语法以及TaskPool(任务池)。
1. 处理I/O密集型异步操作(网络、数据库、文件)
对于你提到的数据库查询、网络请求和文件读写,这些都属于I/O密集型任务。最佳实践是使用async/await语法配合返回Promise的API,使代码逻辑清晰,避免回调地狱。
- 网络请求:使用
@ohos.net.http模块,其方法(如http.createHttp().request)本身是异步的。在async函数内使用await调用,UI线程就不会被阻塞。async function fetchData(url: string): Promise<void> { try { let response = await http.createHttp().request(url, { method: http.RequestMethod.GET }); console.info('Result:', response.result); // 更新UI(ArkUI框架会自动处理线程安全) } catch (error) { console.error('Request failed:', error); } } - 数据库/文件操作:
@ohos.data.relationalStore(关系型数据库)和@ohos.file.fs(文件系统)的关键API也提供了基于Promise的异步接口。务必在async函数中使用await调用,例如await store.query(...)或await fs.readText(...)。
2. 处理CPU密集型异步操作与多任务协调
当需要执行计算密集型任务(如图像处理、复杂算法)或协调多个异步操作时,为了不阻塞UI线程,应使用TaskPool。
-
使用TaskPool:它是轻量级线程池,适用于耗时计算。将函数派发到任务池执行,返回一个
Promise。import taskpool from '@ohos.taskpool'; @Concurrent function computeHeavyTask(data: number): number { // 执行复杂计算 return data * data; } async function runTask(): Promise<void> { let task = new taskpool.Task(computeHeavyTask, 100); let result = await taskpool.execute(task); // 在任务池异步执行 console.info('Result:', result); // 更新UI }注意:传递给
TaskPool的函数必须用@Concurrent装饰器标记,且参数和返回值需支持序列化。 -
协调多个异步操作:
- 并行执行:使用
Promise.all(),当所有异步操作完成时继续。
async function parallelTasks(): Promise<void> { let [dbResult, fileResult] = await Promise.all([ queryDatabase(), readFileContent() ]); // 两者都完成后处理 }- 串行/链式执行:直接使用
await顺序调用,或使用Promise链。
- 并行执行:使用
3. 关键原则与性能要点
- UI线程唯一:所有UI更新必须在主线程(UI线程)进行。异步操作获取数据后,在
async函数中直接更新状态变量(如@State装饰的变量),ArkUI框架会确保UI更新是线程安全的。 - 合理选择工具:I/O等待型任务用
async/await;纯CPU计算型任务,特别是耗时的,用TaskPool。 - 避免阻塞:绝对不要在UI线程上执行同步的耗时操作(如大规模循环计算、同步网络请求)。这会导致应用界面“卡死”。
- 错误处理:务必用
try...catch包裹await调用,或为Promise添加.catch(),以妥善处理异步错误。
通过将数据库、网络、文件等阻塞性操作异步化,并将CPU密集型任务卸载到TaskPool,可以显著提升应用的响应速度与流畅度,这是HarmonyOS Next开发中优化性能的基础手段。

