JavaScript异步编程终极方案:Async/Await高级应用实战
一、Async/Await核心原理
Async函数是Generator函数的语法糖,基于Promise实现:
// 传统Promise链
function fetchData() {
return fetch('/api/data')
.then(response => response.json())
.then(data => processData(data))
.catch(error => handleError(error));
}
// Async/Await等效实现
async function fetchData() {
try {
const response = await fetch('/api/data');
const data = await response.json();
return processData(data);
} catch (error) {
handleError(error);
}
}
二、高级应用技巧
1. 并行执行优化
// 错误方式 - 顺序执行
async function getResults() {
const a = await fetchA(); // 等待完成
const b = await fetchB(); // 才开始
return { a, b };
}
// 正确方式 - 并行执行
async function getResults() {
const [a, b] = await Promise.all([
fetchA(),
fetchB()
]);
return { a, b };
}
2. 错误处理模式
// 方案1:try-catch块
async function fetchWithRetry(url, retries = 3) {
try {
const response = await fetch(url);
return await response.json();
} catch (err) {
if (retries {
try {
return await fn(...args);
} catch (err) {
console.error('操作失败:', err);
return null;
}
};
}
三、实际应用场景
1. 表单提交优化
async function handleSubmit() {
const submitBtn = document.getElementById('submit');
submitBtn.disabled = true;
try {
const formData = gatherFormData();
const validation = validateForm(formData);
if (!validation.valid) {
showErrors(validation.errors);
return;
}
const result = await submitForm(formData);
showSuccess(result);
} catch (error) {
showErrorToast(error.message);
} finally {
submitBtn.disabled = false;
}
}
2. 复杂业务流程
async function placeOrder(userId, products) {
// 1. 验证库存
const inventory = await checkInventory(products);
// 2. 并行执行
const [userInfo, paymentMethods] = await Promise.all([
getUserInfo(userId),
getPaymentMethods(userId)
]);
// 3. 创建订单
const order = await createOrder({
user: userInfo,
products: inventory.availableItems,
payment: paymentMethods[0]
});
// 4. 处理支付
const paymentResult = await processPayment(order);
// 5. 发送通知
await sendConfirmationEmail(userInfo.email, order);
return order;
}
四、性能优化策略
- 请求缓存:Memoization技术避免重复请求
- 提前返回:条件判断后尽早return
- 取消机制:结合AbortController实现
- 批量处理:合并多个异步操作
// 请求缓存实现
const fetchCache = new Map();
async function cachedFetch(url) {
if (fetchCache.has(url)) {
return fetchCache.get(url);
}
const promise = fetch(url).then(r => r.json());
fetchCache.set(url, promise);
return promise;
}
// 取消请求示例
async function fetchWithTimeout(url, timeout = 5000) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, {
signal: controller.signal
});
clearTimeout(timeoutId);
return await response.json();
} catch (err) {
if (err.name === 'AbortError') {
throw new Error('请求超时');
}
throw err;
}
}
五、常见问题解决方案
问题 | 解决方案 |
---|---|
循环中使用await | 使用for…of替代forEach |
全局错误处理 | window.addEventListener(‘unhandledrejection’) |
await Promise.all顺序 | Promise.allSettled+排序 |