${post.title}
${post.content}
深入学习JavaScript异步编程的核心技术
本章将通过实际案例展示Promise在项目中的应用,帮助您将所学知识应用到实际开发中,解决真实世界的问题。
用户注册是一个典型的多步骤异步操作流程,涉及数据验证、API调用、数据库操作等。
// 用户注册服务
class UserRegistrationService {
constructor() {
this.apiEndpoint = '/api/register';
}
// 注册用户
async register(userData) {
try {
// 1. 验证用户数据
await this.validateUserData(userData);
// 2. 检查用户名是否已存在
const isUsernameAvailable = await this.checkUsernameAvailability(userData.username);
if (!isUsernameAvailable) {
throw new Error('用户名已存在');
}
// 3. 检查邮箱是否已存在
const isEmailAvailable = await this.checkEmailAvailability(userData.email);
if (!isEmailAvailable) {
throw new Error('邮箱已被注册');
}
// 4. 创建用户账户
const user = await this.createUserAccount(userData);
// 5. 发送验证邮件
await this.sendVerificationEmail(user.email);
// 6. 记录注册日志
await this.logRegistration(user.id);
return {
success: true,
user: user,
message: '注册成功,请查看邮箱验证账户'
};
} catch (error) {
return {
success: false,
error: error.message,
message: '注册失败: ' + error.message
};
}
}
// 验证用户数据
validateUserData(userData) {
return new Promise((resolve, reject) => {
// 模拟数据验证
setTimeout(() => {
if (!userData.username || userData.username.length < 3) {
reject(new Error('用户名至少需要3个字符'));
} else if (!userData.email || !this.isValidEmail(userData.email)) {
reject(new Error('请输入有效的邮箱地址'));
} else if (!userData.password || userData.password.length < 6) {
reject(new Error('密码至少需要6个字符'));
} else {
resolve(true);
}
}, 100);
});
}
// 检查用户名可用性
checkUsernameAvailability(username) {
return new Promise((resolve) => {
// 模拟API调用
setTimeout(() => {
// 模拟数据库查询结果
const existingUsernames = ['admin', 'user1', 'test'];
resolve(!existingUsernames.includes(username));
}, 200);
});
}
// 检查邮箱可用性
checkEmailAvailability(email) {
return new Promise((resolve) => {
// 模拟API调用
setTimeout(() => {
// 模拟数据库查询结果
const existingEmails = ['admin@example.com', 'user1@example.com'];
resolve(!existingEmails.includes(email));
}, 200);
});
}
// 创建用户账户
createUserAccount(userData) {
return new Promise((resolve) => {
// 模拟API调用
setTimeout(() => {
const user = {
id: Math.floor(Math.random() * 10000),
username: userData.username,
email: userData.email,
createdAt: new Date().toISOString()
};
resolve(user);
}, 300);
});
}
// 发送验证邮件
sendVerificationEmail(email) {
return new Promise((resolve, reject) => {
// 模拟邮件发送
setTimeout(() => {
// 模拟邮件发送成功率
if (Math.random() > 0.1) {
resolve({ messageId: 'msg_' + Date.now() });
} else {
reject(new Error('邮件发送失败'));
}
}, 500);
});
}
// 记录注册日志
logRegistration(userId) {
return new Promise((resolve) => {
// 模拟日志记录
setTimeout(() => {
console.log(`用户 ${userId} 注册成功`);
resolve(true);
}, 100);
});
}
// 验证邮箱格式
isValidEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
}
// 使用用户注册服务
const registrationService = new UserRegistrationService();
// 注册表单提交处理
async function handleRegistrationSubmit(event) {
event.preventDefault();
const formData = new FormData(event.target);
const userData = {
username: formData.get('username'),
email: formData.get('email'),
password: formData.get('password')
};
// 显示加载状态
showLoadingIndicator();
try {
const result = await registrationService.register(userData);
if (result.success) {
showSuccessMessage(result.message);
// 重定向到验证页面
setTimeout(() => {
window.location.href = '/verify-email.html';
}, 2000);
} else {
showErrorMessage(result.message);
}
} catch (error) {
showErrorMessage('注册过程中发生未知错误');
console.error('注册失败:', error);
} finally {
hideLoadingIndicator();
}
}
// 辅助函数
function showLoadingIndicator() {
document.getElementById('loading').style.display = 'block';
}
function hideLoadingIndicator() {
document.getElementById('loading').style.display = 'none';
}
function showSuccessMessage(message) {
const messageEl = document.getElementById('message');
messageEl.textContent = message;
messageEl.className = 'success-message';
messageEl.style.display = 'block';
}
function showErrorMessage(message) {
const messageEl = document.getElementById('message');
messageEl.textContent = message;
messageEl.className = 'error-message';
messageEl.style.display = 'block';
}
在Web应用中,数据获取和缓存是常见的需求,Promise可以帮助我们实现高效的缓存机制。
// 数据缓存服务
class DataCacheService {
constructor() {
this.cache = new Map();
this.pendingRequests = new Map();
}
// 获取数据(带缓存)
async fetchData(key, fetchFn, ttl = 300000) { // 默认缓存5分钟
// 检查是否有正在进行的相同请求
if (this.pendingRequests.has(key)) {
return this.pendingRequests.get(key);
}
// 检查缓存
const cached = this.cache.get(key);
if (cached && Date.now() - cached.timestamp < ttl) {
return cached.data;
}
// 创建新的请求Promise
const requestPromise = this.makeRequest(key, fetchFn);
this.pendingRequests.set(key, requestPromise);
try {
const data = await requestPromise;
// 缓存数据
this.cache.set(key, {
data: data,
timestamp: Date.now()
});
return data;
} finally {
// 清除正在进行的请求
this.pendingRequests.delete(key);
}
}
// 执行实际请求
async makeRequest(key, fetchFn) {
try {
const data = await fetchFn();
return data;
} catch (error) {
console.error(`获取数据失败 (${key}):`, error);
throw error;
}
}
// 清除缓存
clearCache(key) {
if (key) {
this.cache.delete(key);
} else {
this.cache.clear();
}
}
// 获取缓存统计信息
getCacheStats() {
return {
cacheSize: this.cache.size,
pendingRequests: this.pendingRequests.size
};
}
}
// API服务
class ApiService {
constructor() {
this.baseURL = '/api';
this.cacheService = new DataCacheService();
}
// 获取用户信息
async getUser(userId) {
return this.cacheService.fetchData(
`user_${userId}`,
() => this.fetchUser(userId),
600000 // 缓存10分钟
);
}
// 实际获取用户信息的API调用
async fetchUser(userId) {
const response = await fetch(`${this.baseURL}/users/${userId}`);
if (!response.ok) {
throw new Error(`获取用户信息失败: ${response.status}`);
}
return response.json();
}
// 获取用户帖子
async getUserPosts(userId) {
return this.cacheService.fetchData(
`user_posts_${userId}`,
() => this.fetchUserPosts(userId),
300000 // 缓存5分钟
);
}
// 实际获取用户帖子的API调用
async fetchUserPosts(userId) {
const response = await fetch(`${this.baseURL}/users/${userId}/posts`);
if (!response.ok) {
throw new Error(`获取用户帖子失败: ${response.status}`);
}
return response.json();
}
// 获取帖子评论
async getPostComments(postId) {
return this.cacheService.fetchData(
`post_comments_${postId}`,
() => this.fetchPostComments(postId),
180000 // 缓存3分钟
);
}
// 实际获取帖子评论的API调用
async fetchPostComments(postId) {
const response = await fetch(`${this.baseURL}/posts/${postId}/comments`);
if (!response.ok) {
throw new Error(`获取帖子评论失败: ${response.status}`);
}
return response.json();
}
// 清除特定用户的缓存
clearUserCache(userId) {
this.cacheService.clearCache(`user_${userId}`);
this.cacheService.clearCache(`user_posts_${userId}`);
}
// 获取缓存统计
getCacheStats() {
return this.cacheService.getCacheStats();
}
}
// 使用API服务
const apiService = new ApiService();
// 加载用户详情页面
async function loadUserDetail(userId) {
try {
showLoading();
// 并行获取用户信息和帖子
const [user, posts] = await Promise.all([
apiService.getUser(userId),
apiService.getUserPosts(userId)
]);
// 显示用户信息
displayUser(user);
// 显示帖子列表
displayPosts(posts);
// 获取第一个帖子的评论(串行)
if (posts.length > 0) {
const comments = await apiService.getPostComments(posts[0].id);
displayComments(comments);
}
} catch (error) {
showErrorMessage('加载用户信息失败: ' + error.message);
console.error('加载用户详情失败:', error);
} finally {
hideLoading();
}
}
// 辅助函数
function showLoading() {
document.getElementById('loading').style.display = 'block';
}
function hideLoading() {
document.getElementById('loading').style.display = 'none';
}
function displayUser(user) {
document.getElementById('user-name').textContent = user.name;
document.getElementById('user-email').textContent = user.email;
}
function displayPosts(posts) {
const postsContainer = document.getElementById('posts-container');
postsContainer.innerHTML = posts.map(post => `
${post.title}
${post.content}
`).join('');
}
function displayComments(comments) {
const commentsContainer = document.getElementById('comments-container');
commentsContainer.innerHTML = comments.map(comment => `
文件上传是Web应用中的常见功能,涉及文件验证、上传进度、并发控制等。
// 文件上传服务
class FileUploadService {
constructor(options = {}) {
this.maxFileSize = options.maxFileSize || 10 * 1024 * 1024; // 默认10MB
this.allowedTypes = options.allowedTypes || ['image/jpeg', 'image/png', 'image/gif'];
this.maxConcurrentUploads = options.maxConcurrentUploads || 3;
this.uploadQueue = [];
this.activeUploads = 0;
}
// 验证文件
validateFile(file) {
return new Promise((resolve, reject) => {
// 检查文件大小
if (file.size > this.maxFileSize) {
reject(new Error(`文件大小超过限制 (${this.formatFileSize(this.maxFileSize)})`));
return;
}
// 检查文件类型
if (!this.allowedTypes.includes(file.type)) {
reject(new Error(`不支持的文件类型: ${file.type}`));
return;
}
// 对于图片文件,可以进行额外的验证
if (file.type.startsWith('image/')) {
const img = new Image();
img.onload = () => {
resolve({ width: img.width, height: img.height });
};
img.onerror = () => {
reject(new Error('无效的图片文件'));
};
img.src = URL.createObjectURL(file);
} else {
resolve(true);
}
});
}
// 上传单个文件
uploadFile(file, onProgress) {
return new Promise((resolve, reject) => {
// 验证文件
this.validateFile(file)
.then(() => {
// 创建FormData
const formData = new FormData();
formData.append('file', file);
// 创建XMLHttpRequest
const xhr = new XMLHttpRequest();
// 监听上传进度
xhr.upload.addEventListener('progress', (event) => {
if (event.lengthComputable && onProgress) {
const percentComplete = (event.loaded / event.total) * 100;
onProgress(percentComplete);
}
});
// 监听请求完成
xhr.addEventListener('load', () => {
if (xhr.status >= 200 && xhr.status < 300) {
try {
const response = JSON.parse(xhr.responseText);
resolve(response);
} catch (e) {
resolve({ url: xhr.responseText });
}
} else {
reject(new Error(`上传失败: ${xhr.status}`));
}
});
// 监听错误
xhr.addEventListener('error', () => {
reject(new Error('网络错误,上传失败'));
});
// 发送请求
xhr.open('POST', '/api/upload');
xhr.send(formData);
})
.catch(reject);
});
}
// 批量上传文件(控制并发数)
async uploadFiles(files, onProgress) {
const results = [];
const errors = [];
// 分批处理文件
for (let i = 0; i < files.length; i += this.maxConcurrentUploads) {
const batch = files.slice(i, i + this.maxConcurrentUploads);
const batchPromises = batch.map((file, index) => {
const fileIndex = i + index;
return this.uploadFile(file, (progress) => {
if (onProgress) {
onProgress(fileIndex, progress);
}
}).then(result => {
results[fileIndex] = result;
return result;
}).catch(error => {
errors[fileIndex] = error;
throw error;
});
});
try {
await Promise.all(batchPromises);
} catch (error) {
// 继续处理其他批次
console.warn('批次上传出错:', error);
}
}
return { results, errors };
}
// 取消上传
cancelUpload(xhr) {
if (xhr && xhr.readyState !== XMLHttpRequest.DONE) {
xhr.abort();
}
}
// 格式化文件大小
formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
}
// 使用文件上传服务
const uploadService = new FileUploadService({
maxFileSize: 5 * 1024 * 1024, // 5MB
allowedTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf'],
maxConcurrentUploads: 2
});
// 处理文件选择
async function handleFileSelect(event) {
const files = Array.from(event.target.files);
const uploadContainer = document.getElementById('upload-container');
// 清空之前的上传状态
uploadContainer.innerHTML = '';
// 为每个文件创建上传状态显示
files.forEach((file, index) => {
const fileElement = document.createElement('div');
fileElement.className = 'file-upload';
fileElement.innerHTML = `
${file.name}
${uploadService.formatFileSize(file.size)}
等待上传
`;
uploadContainer.appendChild(fileElement);
});
// 开始上传
try {
const { results, errors } = await uploadService.uploadFiles(files, (fileIndex, progress) => {
// 更新进度显示
const progressFill = document.getElementById(`progress-${fileIndex}`);
const progressText = document.getElementById(`progress-text-${fileIndex}`);
if (progressFill && progressText) {
progressFill.style.width = `${progress}%`;
progressText.textContent = `${Math.round(progress)}%`;
}
});
// 显示上传结果
results.forEach((result, index) => {
if (result) {
const resultElement = document.getElementById(`result-${index}`);
if (resultElement) {
resultElement.innerHTML = `
上传成功`;
if (result.url) {
resultElement.innerHTML += `
查看文件`;
}
}
}
});
// 显示错误信息
errors.forEach((error, index) => {
if (error) {
const resultElement = document.getElementById(`result-${index}`);
if (resultElement) {
resultElement.innerHTML = `上传失败: ${error.message}`;
}
}
});
} catch (error) {
console.error('批量上传失败:', error);
showErrorMessage('文件上传过程中发生错误');
}
}
// 辅助函数
function showErrorMessage(message) {
const errorEl = document.getElementById('error-message');
if (errorEl) {
errorEl.textContent = message;
errorEl.style.display = 'block';
}
}
在现代Web应用中,实时数据同步是提升用户体验的重要功能。
// 实时数据同步服务
class RealtimeSyncService {
constructor(options = {}) {
this.syncInterval = options.syncInterval || 30000; // 默认30秒同步一次
this.retryInterval = options.retryInterval || 5000; // 默认5秒重试
this.maxRetries = options.maxRetries || 3;
this.syncUrl = options.syncUrl || '/api/sync';
this.isSyncing = false;
this.syncTimer = null;
this.retryCount = 0;
this.subscribers = [];
}
// 启动同步
startSync() {
if (this.syncTimer) {
clearInterval(this.syncTimer);
}
this.syncTimer = setInterval(() => {
this.syncData();
}, this.syncInterval);
// 立即执行一次同步
this.syncData();
}
// 停止同步
stopSync() {
if (this.syncTimer) {
clearInterval(this.syncTimer);
this.syncTimer = null;
}
}
// 手动触发同步
async syncData() {
if (this.isSyncing) {
console.log('同步正在进行中,跳过本次同步');
return;
}
this.isSyncing = true;
this.notifySubscribers('syncStart');
try {
// 获取本地待同步的数据
const localChanges = this.getLocalChanges();
if (localChanges.length > 0) {
// 发送同步请求
const response = await this.sendSyncRequest(localChanges);
// 处理同步响应
await this.processSyncResponse(response);
// 清除已同步的本地数据
this.clearLocalChanges(localChanges);
this.retryCount = 0; // 重置重试计数
this.notifySubscribers('syncSuccess', response);
} else {
this.notifySubscribers('syncNoChanges');
}
} catch (error) {
console.error('数据同步失败:', error);
this.notifySubscribers('syncError', error);
// 处理重试逻辑
if (this.retryCount < this.maxRetries) {
this.retryCount++;
console.log(`同步失败,${this.retryInterval/1000}秒后重试 (${this.retryCount}/${this.maxRetries})`);
setTimeout(() => {
this.isSyncing = false;
this.syncData();
}, this.retryInterval);
return;
} else {
this.retryCount = 0;
this.notifySubscribers('syncFailedPermanently', error);
}
} finally {
this.isSyncing = false;
}
}
// 获取本地待同步的数据
getLocalChanges() {
try {
const changes = localStorage.getItem('pendingChanges');
return changes ? JSON.parse(changes) : [];
} catch (error) {
console.error('解析本地变更数据失败:', error);
return [];
}
}
// 发送同步请求
async sendSyncRequest(changes) {
const response = await fetch(this.syncUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.getAuthToken()}`
},
body: JSON.stringify({ changes })
});
if (!response.ok) {
throw new Error(`同步请求失败: ${response.status}`);
}
return response.json();
}
// 处理同步响应
async processSyncResponse(response) {
// 更新本地数据
if (response.updates && response.updates.length > 0) {
for (const update of response.updates) {
await this.updateLocalData(update);
}
}
// 处理冲突
if (response.conflicts && response.conflicts.length > 0) {
await this.resolveConflicts(response.conflicts);
}
// 通知数据更新
this.notifySubscribers('dataUpdated', response);
}
// 清除已同步的本地数据
clearLocalChanges(syncedChanges) {
try {
const pendingChanges = this.getLocalChanges();
const remainingChanges = pendingChanges.filter(change =>
!syncedChanges.some(synced => synced.id === change.id)
);
if (remainingChanges.length > 0) {
localStorage.setItem('pendingChanges', JSON.stringify(remainingChanges));
} else {
localStorage.removeItem('pendingChanges');
}
} catch (error) {
console.error('清除已同步数据失败:', error);
}
}
// 更新本地数据
async updateLocalData(update) {
// 这里实现具体的本地数据更新逻辑
console.log('更新本地数据:', update);
// 例如:更新IndexedDB、localStorage等
}
// 解决冲突
async resolveConflicts(conflicts) {
// 这里实现冲突解决逻辑
console.log('解决数据冲突:', conflicts);
// 例如:使用最后写入获胜策略、用户选择等
}
// 获取认证令牌
getAuthToken() {
// 这里实现获取认证令牌的逻辑
return localStorage.getItem('authToken') || '';
}
// 订阅同步事件
subscribe(callback) {
this.subscribers.push(callback);
return () => {
const index = this.subscribers.indexOf(callback);
if (index > -1) {
this.subscribers.splice(index, 1);
}
};
}
// 通知订阅者
notifySubscribers(event, data) {
this.subscribers.forEach(callback => {
try {
callback(event, data);
} catch (error) {
console.error('通知订阅者时出错:', error);
}
});
}
// 强制同步
async forceSync() {
// 清除定时器,立即执行同步
if (this.syncTimer) {
clearInterval(this.syncTimer);
}
await this.syncData();
// 重新启动定时同步
this.startSync();
}
}
// 使用实时同步服务
const syncService = new RealtimeSyncService({
syncInterval: 60000, // 1分钟同步一次
retryInterval: 10000, // 10秒重试
maxRetries: 5
});
// 启动同步服务
syncService.startSync();
// 订阅同步事件
const unsubscribe = syncService.subscribe((event, data) => {
switch (event) {
case 'syncStart':
console.log('开始数据同步');
showSyncStatus('同步中...');
break;
case 'syncSuccess':
console.log('数据同步成功', data);
showSyncStatus('同步完成');
updateUI(data);
break;
case 'syncNoChanges':
console.log('没有需要同步的数据');
showSyncStatus('数据已同步');
break;
case 'syncError':
console.error('数据同步出错:', data);
showSyncStatus('同步失败');
showErrorMessage('数据同步失败: ' + data.message);
break;
case 'syncFailedPermanently':
console.error('数据同步永久失败:', data);
showSyncStatus('同步失败');
showErrorMessage('数据同步失败,请检查网络连接');
break;
case 'dataUpdated':
console.log('数据已更新', data);
updateUI(data);
break;
}
});
// 辅助函数
function showSyncStatus(message) {
const statusEl = document.getElementById('sync-status');
if (statusEl) {
statusEl.textContent = message;
}
}
function showErrorMessage(message) {
const errorEl = document.getElementById('error-message');
if (errorEl) {
errorEl.textContent = message;
errorEl.style.display = 'block';
}
}
function updateUI(data) {
// 更新界面显示
console.log('更新界面显示', data);
}
// 页面卸载时停止同步
window.addEventListener('beforeunload', () => {
syncService.stopSync();
unsubscribe();
});
在不稳定的网络环境中,实现健壮的错误恢复和重试机制非常重要。
// 带重试机制的HTTP客户端
class RetryableHttpClient {
constructor(options = {}) {
this.maxRetries = options.maxRetries || 3;
this.retryDelay = options.retryDelay || 1000;
this.exponentialBackoff = options.exponentialBackoff || true;
this.retryableStatusCodes = options.retryableStatusCodes || [408, 429, 500, 502, 503, 504];
this.retryableErrors = options.retryableErrors || ['NetworkError', 'TimeoutError'];
}
// 发送HTTP请求(带重试机制)
async request(url, options = {}) {
let lastError;
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
try {
const response = await this.makeRequest(url, options);
// 检查是否需要重试
if (attempt < this.maxRetries && this.shouldRetry(response)) {
const delay = this.calculateDelay(attempt);
console.log(`请求失败,${delay}ms后进行第${attempt + 1}次重试`);
await this.delay(delay);
continue;
}
return response;
} catch (error) {
lastError = error;
// 检查是否应该重试
if (attempt < this.maxRetries && this.shouldRetryError(error)) {
const delay = this.calculateDelay(attempt);
console.log(`请求出错,${delay}ms后进行第${attempt + 1}次重试:`, error.message);
await this.delay(delay);
continue;
}
throw error;
}
}
throw lastError;
}
// 执行实际的HTTP请求
async makeRequest(url, options) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
// 设置超时
xhr.timeout = options.timeout || 10000;
xhr.addEventListener('load', () => {
const response = {
status: xhr.status,
statusText: xhr.statusText,
headers: this.parseHeaders(xhr.getAllResponseHeaders()),
data: xhr.responseText
};
try {
response.data = JSON.parse(xhr.responseText);
} catch (e) {
// 如果不是JSON,保持原始文本
}
resolve(response);
});
xhr.addEventListener('error', () => {
reject(new Error('网络错误'));
});
xhr.addEventListener('timeout', () => {
reject(new Error('请求超时'));
});
try {
xhr.open(options.method || 'GET', url);
// 设置请求头
if (options.headers) {
Object.keys(options.headers).forEach(key => {
xhr.setRequestHeader(key, options.headers[key]);
});
}
// 发送请求
xhr.send(options.body ? JSON.stringify(options.body) : null);
} catch (error) {
reject(new Error('请求发送失败: ' + error.message));
}
});
}
// 判断是否应该重试(基于响应状态码)
shouldRetry(response) {
return this.retryableStatusCodes.includes(response.status);
}
// 判断是否应该重试(基于错误类型)
shouldRetryError(error) {
return this.retryableErrors.some(retryableError =>
error.name === retryableError || error.message.includes(retryableError)
);
}
// 计算重试延迟
calculateDelay(attempt) {
let delay = this.retryDelay;
if (this.exponentialBackoff) {
delay *= Math.pow(2, attempt);
}
// 添加随机抖动以避免惊群效应
const jitter = Math.random() * 1000;
return delay + jitter;
}
// 延迟函数
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// 解析响应头
parseHeaders(headerStr) {
const headers = {};
if (!headerStr) return headers;
const headerPairs = headerStr.trim().split(/\r?\n/);
for (const headerPair of headerPairs) {
const index = headerPair.indexOf(':');
if (index > 0) {
const key = headerPair.substring(0, index).trim().toLowerCase();
const value = headerPair.substring(index + 1).trim();
headers[key] = value;
}
}
return headers;
}
// GET请求
async get(url, options = {}) {
return this.request(url, { ...options, method: 'GET' });
}
// POST请求
async post(url, data, options = {}) {
return this.request(url, {
...options,
method: 'POST',
headers: {
'Content-Type': 'application/json',
...(options.headers || {})
},
body: data
});
}
// PUT请求
async put(url, data, options = {}) {
return this.request(url, {
...options,
method: 'PUT',
headers: {
'Content-Type': 'application/json',
...(options.headers || {})
},
body: data
});
}
// DELETE请求
async delete(url, options = {}) {
return this.request(url, { ...options, method: 'DELETE' });
}
}
// 使用带重试机制的HTTP客户端
const httpClient = new RetryableHttpClient({
maxRetries: 3,
retryDelay: 1000,
exponentialBackoff: true,
retryableStatusCodes: [408, 429, 500, 502, 503, 504],
retryableErrors: ['NetworkError', 'TimeoutError']
});
// API服务
class ApiService {
constructor() {
this.baseUrl = '/api';
this.httpClient = httpClient;
}
// 获取用户信息
async getUser(userId) {
try {
const response = await this.httpClient.get(`${this.baseUrl}/users/${userId}`);
if (response.status >= 200 && response.status < 300) {
return response.data;
} else {
throw new Error(`获取用户信息失败: ${response.status} ${response.statusText}`);
}
} catch (error) {
console.error('获取用户信息出错:', error);
throw error;
}
}
// 更新用户信息
async updateUser(userId, userData) {
try {
const response = await this.httpClient.put(
`${this.baseUrl}/users/${userId}`,
userData
);
if (response.status >= 200 && response.status < 300) {
return response.data;
} else {
throw new Error(`更新用户信息失败: ${response.status} ${response.statusText}`);
}
} catch (error) {
console.error('更新用户信息出错:', error);
throw error;
}
}
// 删除用户
async deleteUser(userId) {
try {
const response = await this.httpClient.delete(`${this.baseUrl}/users/${userId}`);
if (response.status >= 200 && response.status < 300) {
return true;
} else {
throw new Error(`删除用户失败: ${response.status} ${response.statusText}`);
}
} catch (error) {
console.error('删除用户出错:', error);
throw error;
}
}
}
// 使用API服务
const apiService = new ApiService();
// 用户操作处理
async function handleUserOperations() {
try {
// 获取用户信息
const user = await apiService.getUser(123);
console.log('用户信息:', user);
// 更新用户信息
const updatedUser = await apiService.updateUser(123, {
name: '新名字',
email: 'new@example.com'
});
console.log('更新后的用户信息:', updatedUser);
// 删除用户
const isDeleted = await apiService.deleteUser(123);
console.log('用户删除结果:', isDeleted);
} catch (error) {
console.error('用户操作失败:', error);
showErrorMessage('操作失败: ' + error.message);
}
}
// 辅助函数
function showErrorMessage(message) {
const errorEl = document.getElementById('error-message');
if (errorEl) {
errorEl.textContent = message;
errorEl.style.display = 'block';
}
}
// 执行用户操作
handleUserOperations();
提示:在实际项目中,这些示例需要根据具体需求进行调整和完善。务必考虑安全性、性能、错误处理和用户体验等方面。
${comment.content}
by ${comment.author}