在现代JavaScript异步编程中,错误处理是确保应用稳定性的关键环节。本文将通过实际代码示例展示Promise和async/await中的错误处理最佳实践。
Promise错误处理
传统的Promise链式调用中,.catch()方法用于捕获错误。让我们看一个典型的API调用场景:
function fetchUserData(userId) {
return fetch(`/api/users/${userId}`)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.catch(error => {
console.error('Fetch failed:', error);
throw new Error(`User fetch failed for ID ${userId}`);
});
}
// 使用示例
fetchUserData(123)
.then(user => console.log('User data:', user))
.catch(error => console.error('Error:', error.message));
async/await错误处理
使用async/await时,可以采用try/catch结构来处理异步错误:
async function getUserProfile(userId) {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const userData = await response.json();
// 模拟数据验证错误
if (!userData.email) {
throw new Error('User email is required');
}
return userData;
} catch (error) {
console.error('User profile fetch failed:', error.message);
// 可以选择重新抛出或返回默认值
throw new Error(`Failed to get profile for user ${userId}`);
}
}
// 调用示例
async function displayUserProfile() {
try {
const profile = await getUserProfile(456);
console.log('Profile:', profile);
} catch (error) {
console.error('Display error:', error.message);
// 显示用户友好的错误信息
document.getElementById('error-message').textContent = '无法加载用户资料';
}
}
综合错误处理策略
在复杂应用中,建议采用统一的错误处理机制:
// 创建错误处理器
const errorHandler = {
handle: (error, context) => {
console.error(`[${context}] Error occurred:`, error);
// 根据错误类型进行不同处理
if (error.name === 'TypeError') {
// 网络错误或请求失败
return { type: 'NETWORK_ERROR', message: '网络连接异常' };
} else if (error.message.includes('HTTP')) {
// HTTP状态码错误
return { type: 'API_ERROR', message: '服务器响应错误' };
}
return { type: 'UNKNOWN_ERROR', message: '未知错误' };
}
};
// 在异步函数中使用
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) {
if (i === maxRetries - 1) {
// 最后一次重试失败,抛出错误
throw errorHandler.handle(error, 'FETCH_DATA');
}
// 等待后重试
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
}
}
}
通过这些实践,可以构建更加健壮的异步JavaScript应用,确保在各种异常情况下都能优雅地处理错误并提供良好的用户体验。

讨论