在现代JavaScript异步编程中,async-await虽然让异步代码看起来像同步代码,但错误处理依然是开发者需要重点关注的环节。本文将通过实际案例展示几种常见的async-await错误恢复策略。
基础错误捕获
首先,让我们看一个简单的HTTP请求示例:
async function fetchUserData(userId) {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('获取用户数据失败:', error.message);
// 返回默认值或重新抛出错误
return null;
}
}
// 使用示例
const user = await fetchUserData(123);
if (user) {
console.log('用户信息:', user);
} else {
console.log('使用默认用户信息');
}
错误重试机制
对于网络请求,我们经常需要实现错误重试逻辑:
async function fetchWithRetry(url, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
console.warn(`请求失败,第${i + 1}次重试:`, error.message);
if (i === maxRetries - 1) throw error; // 最后一次尝试仍失败则抛出
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1))); // 指数退避
}
}
}
// 使用示例
try {
const data = await fetchWithRetry('/api/data');
console.log('数据获取成功:', data);
} catch (error) {
console.error('所有重试都失败了:', error.message);
}
并发错误处理
当需要同时处理多个异步操作时,错误恢复策略更加复杂:
async function fetchMultipleUsers(userIds) {
// 方法1: 使用Promise.allSettled
const promises = userIds.map(id => fetchUserData(id));
const results = await Promise.allSettled(promises);
const successful = [];
const failed = [];
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
successful.push({ id: userIds[index], data: result.value });
} else {
failed.push({ id: userIds[index], error: result.reason.message });
}
});
return { successful, failed };
}
// 使用示例
const { successful, failed } = await fetchMultipleUsers([1, 2, 3]);
console.log('成功:', successful);
console.log('失败:', failed);
自定义错误恢复函数
对于复杂的业务场景,我们可以封装通用的错误恢复逻辑:
function createErrorHandler(defaultValue = null, retryCount = 0) {
return async function (asyncFunction, ...args) {
try {
return await asyncFunction(...args);
} catch (error) {
console.error('操作失败:', error.message);
if (retryCount > 0) {
console.log(`重试 ${retryCount} 次...`);
// 实现重试逻辑
return defaultValue;
}
throw error; // 重新抛出错误
}
};
}
const safeFetch = createErrorHandler(null, 2);
const user = await safeFetch(fetchUserData, 123);
通过这些策略,我们可以在async-await中构建更加健壮的错误恢复机制,确保应用在面对网络异常、服务器错误等情况下仍能优雅地处理。

讨论