JavaScript高级异步编程实战:Promise与Async/Await深度解析
一、异步编程演进历程
JavaScript异步编程经历了三个阶段:
- 回调函数阶段:容易导致”回调地狱”
- Promise阶段:ES6引入的解决方案
- Async/Await阶段:ES2017提供的语法糖
二、Promise核心原理
1. 基本用法
const promise = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
const success = Math.random() > 0.5;
success ? resolve('操作成功') : reject('操作失败');
}, 1000);
});
promise
.then(result => console.log(result))
.catch(error => console.error(error));
2. 链式调用
function fetchUser(id) {
return new Promise(resolve => {
setTimeout(() => resolve({id, name: `用户${id}`}), 500);
});
}
fetchUser(1)
.then(user => {
console.log('获取用户:', user);
return fetchUser(2);
})
.then(user => console.log('获取好友:', user))
.catch(error => console.error(error));
三、Async/Await实战
1. 基本用法
async function getUserInfo(userId) {
try {
const user = await fetchUser(userId);
const posts = await fetchPosts(user.id);
return {user, posts};
} catch (error) {
console.error('获取数据失败:', error);
throw error;
}
}
getUserInfo(1).then(data => console.log(data));
2. 并行请求优化
async function getDashboardData(userId) {
const [user, posts, notifications] = await Promise.all([
fetchUser(userId),
fetchPosts(userId),
fetchNotifications(userId)
]);
return {user, posts, notifications};
}
四、高级应用场景
1. 超时控制实现
function withTimeout(promise, timeout) {
return Promise.race([
promise,
new Promise((_, reject) =>
setTimeout(() => reject(new Error('请求超时')), timeout)
)
]);
}
// 使用示例
withTimeout(fetchUser(1), 1000)
.then(user => console.log(user))
.catch(error => console.error(error));
2. 自动重试机制
async function retry(fn, retries = 3, delay = 1000) {
try {
return await fn();
} catch (error) {
if (retries setTimeout(res, delay));
return retry(fn, retries - 1, delay * 2);
}
}
// 使用示例
retry(() => fetch('https://api.example.com/data'))
.then(data => console.log(data))
.catch(error => console.error('最终失败:', error));
五、性能优化技巧
- 避免不必要的await:独立操作应该并行执行
- 合理使用Promise缓存:相同请求避免重复执行
- 批量处理异步任务:使用Promise.all提高效率
- 错误处理要全面:不要忽略catch块