JavaScript高级异步编程:Promise与Async/Await实战全解析
一、Promise核心机制
现代JavaScript异步编程的基础构建块:
// 创建Promise的三种状态
const pending = new Promise((resolve, reject) => {});
const fulfilled = Promise.resolve('成功值');
const rejected = Promise.reject(new Error('失败原因'));
// 链式调用示例
function fetchUserData(userId) {
return fetch(`/api/users/${userId}`)
.then(response => {
if (!response.ok) {
throw new Error('网络响应异常');
}
return response.json();
})
.then(user => {
console.log('获取用户数据:', user);
return user;
})
.catch(error => {
console.error('获取数据失败:', error);
throw error; // 继续传递错误
});
}
关键特性:状态不可逆、链式调用、错误冒泡、微任务队列
二、高级异步模式
1. 并发控制实现
// 限制并发数量的Promise执行器
async function promisePool(tasks, poolLimit) {
const executing = new Set();
const results = [];
for (const task of tasks) {
const p = Promise.resolve().then(() => task());
results.push(p);
executing.add(p);
const clean = () => executing.delete(p);
p.then(clean).catch(clean);
if (executing.size >= poolLimit) {
await Promise.race(executing);
}
}
return Promise.all(results);
}
// 使用示例
const urls = [...Array(100).keys()].map(i => `https://example.com/api/${i}`);
const fetchTasks = urls.map(url => () => fetch(url).then(r => r.json()));
promisePool(fetchTasks, 5)
.then(data => console.log('所有请求完成', data));
2. 取消Promise方案
// 可取消的Promise包装器
function makeCancelable(promise) {
let hasCanceled = false;
const wrappedPromise = new Promise((resolve, reject) => {
promise.then(
val => hasCanceled ? reject({isCanceled: true}) : resolve(val),
err => hasCanceled ? reject({isCanceled: true}) : reject(err)
);
});
return {
promise: wrappedPromise,
cancel() {
hasCanceled = true;
}
};
}
// 使用示例
const { promise, cancel } = makeCancelable(
fetch('https://api.example.com/data')
);
promise
.then(data => console.log(data))
.catch(err => {
if (err.isCanceled) {
console.log('请求已被取消');
} else {
console.error('请求失败', err);
}
});
// 取消请求
setTimeout(() => cancel(), 1000);
三、Async/Await最佳实践
1. 错误处理模式
// 优化后的async/await错误处理
async function getUserPosts(userId) {
try {
// 并行请求优化
const [user, posts] = await Promise.all([
fetchUser(userId),
fetchPosts(userId)
]);
if (!user.isActive) {
throw new Error('用户已停用');
}
return { user, posts };
} catch (error) {
// 错误分类处理
if (error instanceof TypeError) {
console.error('网络错误:', error);
throw new Error('服务不可用');
} else {
console.error('业务错误:', error);
throw error; // 继续传递
}
} finally {
console.log('请求处理完成');
}
}
// 使用辅助函数简化
async function handleRequest() {
const [err, result] = await to(getUserPosts(123));
if (err) return showError(err);
renderData(result);
}
// to函数实现
function to(promise) {
return promise
.then(data => [null, data])
.catch(err => [err, undefined]);
}
2. 性能优化技巧
// 异步操作缓存策略
const asyncCache = new Map();
async function cachedFetch(url) {
if (asyncCache.has(url)) {
return asyncCache.get(url);
}
const promise = fetch(url)
.then(response => response.json())
.catch(err => {
asyncCache.delete(url); // 失败时移除缓存
throw err;
});
asyncCache.set(url, promise);
return promise;
}
// 批量处理优化
async function processInBatches(items, batchSize, asyncFn) {
const results = [];
for (let i = 0; i setTimeout(resolve, 0));
}
return results;
}
四、电商系统实战案例
1. 订单支付流程
async function handlePayment(order) {
try {
// 1. 验证库存
const inventoryValid = await verifyInventory(order.items);
if (!inventoryValid) {
throw new Error('库存不足');
}
// 2. 创建支付记录
const payment = await createPaymentRecord(order);
// 3. 调用支付网关
const paymentResult = await callPaymentGateway(payment);
// 4. 更新订单状态
await updateOrderStatus(order.id, 'paid');
// 5. 发送通知
await Promise.all([
sendEmailReceipt(order.userEmail, paymentResult),
updateInventory(order.items)
]);
return { success: true, paymentId: payment.id };
} catch (error) {
// 补偿事务
await rollbackPayment(order.id);
await sendPaymentFailureEmail(order.userEmail, error.message);
console.error('支付流程失败:', error);
throw error;
}
}
// 使用示例
handlePayment(currentOrder)
.then(result => showSuccess(result))
.catch(error => showError(error));
五、前沿技术展望
- Top-Level Await:ES模块中的顶级await
- Promise.any:首个成功Promise解决
- Async Context:异步上下文跟踪
- Web Streams API:流式异步处理
- React Suspense:声明式异步UI