异步编程
async/await
学习 async/await 语法、错误处理
async / await
async/await 是 ES2017 引入的语法糖,让异步代码看起来像同步代码。
学完本章你将: 掌握 async/await 语法与错误处理。
基本语法
javascript
// async 函数始终返回 Promise
async function greet() {
return "Hello";
}
greet().then(msg => console.log(msg)); // "Hello"
// await 暂停执行直到 Promise 完成
async function fetchUser(id) {
let response = await fetch(`/api/user/${id}`);
let user = await response.json();
return user;
}
错误处理
javascript
// try-catch
async function loadData() {
try {
let user = await fetchUser(1);
let posts = await fetchPosts(user.id);
console.log(posts);
} catch (error) {
console.error("出错了:", error.message);
} finally {
console.log("清理工作");
}
}
// 或者 .catch()
async function loadData2() {
let user = await fetchUser(1).catch(err => {
console.error(err);
return null;
});
if (!user) return;
// ...
}
并发 vs 顺序
javascript
// 顺序执行(慢)
async function sequential() {
let user = await fetchUser(1); // 等 500ms
let posts = await fetchPosts(1); // 等 500ms
// 总共约 1000ms
}
// 并发执行(快)
async function concurrent() {
let [user, posts] = await Promise.all([
fetchUser(1),
fetchPosts(1),
]);
// 总共约 500ms
}
实战模式
javascript
// 1. 超时控制
async function fetchWithTimeout(url, timeout = 5000) {
let controller = new AbortController();
let timer = setTimeout(() => controller.abort(), timeout);
try {
let response = await fetch(url, { signal: controller.signal });
return response.json();
} finally {
clearTimeout(timer);
}
}
// 2. 重试机制
async function fetchWithRetry(url, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await fetch(url).then(r => r.json());
} catch (err) {
if (i === retries - 1) throw err;
await new Promise(r => setTimeout(r, 1000 * (i + 1)));
}
}
}
// 3. 迭代异步
async function processArray(items) {
for (let item of items) {
await process(item); // 逐个处理
}
}