第9章:多线程与并发
异步编程
1. 异步编程概述
ArkTS中的异步编程模型允许开发者在不阻塞主线程的情况下执行耗时操作(如网络请求、文件I/O等)。通过异步机制,可以保持UI的流畅响应,提升用户体验。
核心概念:
- 同步 vs 异步:同步代码按顺序阻塞执行,异步代码通过回调/Promise等机制非阻塞执行。
- 事件循环:ArkTS基于事件循环模型处理异步任务。
2. Promise与async/await
Promise
function fetchData(): Promise<string> {
return new Promise((resolve, reject) => {
// 模拟异步操作
setTimeout(() => resolve("Data loaded"), 1000);
});
}
fetchData()
.then(data => console.log(data))
.catch(error => console.error(error));
async/await
async function loadData() {
try {
const data = await fetchData();
console.log(data);
} catch (error) {
console.error(error);
}
}
3. 异步任务调度
ArkTS提供任务队列管理机制:
- 微任务(Microtask):通过
Promise.then()或queueMicrotask()调度,优先于宏任务执行。 - 宏任务(Macrotask):如
setTimeout、UI渲染任务等。
执行顺序示例:
console.log("Start");
setTimeout(() => console.log("Timeout"), 0);
Promise.resolve().then(() => console.log("Promise"));
console.log("End");
// 输出顺序: Start → End → Promise → Timeout
4. 异步错误处理
- try/catch:适用于async函数内。
- 全局错误捕获:通过
window.onerror或process.uncaughtException(Node环境)。 - Promise链式捕获:
.catch()或链式调用中的错误冒泡。
5. 实际应用场景
- 网络请求:
async function fetchUser() {
const response = await fetch('https://api.example.com/user');
return await response.json();
}
- 文件操作:
import fs from '@ohos.file.fs';
async function readFile(path: string): Promise<Uint8Array> {
return fs.readFile(path);
}
6. 性能优化建议
- 避免嵌套过深的异步调用(回调地狱)。
- 使用
Promise.all()并行独立任务:
const [user, posts] = await Promise.all([
fetchUser(),
fetchPosts()
]);
- 对高频率异步操作使用防抖/节流。
7. 调试技巧
- 使用
console.time()/console.timeEnd()测量异步耗时。 - 在DevTools中查看异步调用栈。
- 通过
async_hooks模块(Node环境)追踪异步资源。
注意:在UI线程中执行耗时异步操作仍需谨慎,建议将超过50ms的任务移至Worker线程(参见9.1节)。
