Promise 八个优化技巧,让异步代码更丝滑!
写 Promise 就像煮泡面,看似简单但想煮得好吃有讲究!掌握这8个技巧,让你的异步代码从“勉强能用”变成“优雅高效”!
1. 别把 Promise 当回调地狱救生圈 🛟
错误示范(套娃式写法):
getUser().then(user => {
getOrders(user.id).then(orders => {
getOrderDetails(orders[0].id).then(details => {
console.log(details); // 又回到地狱了!
});
});
});
正确姿势(链式调用):
getUser()
.then(user => getOrders(user.id))
.then(orders => getOrderDetails(orders[0].id))
.then(details =>console.log(details))
.catch(error =>console.error('出错了:', error));
2. 一定要加 .catch() 保险 ⛑
错误示范(裸奔很危险):
fetchData().then(data => {
// 万一出错,程序就崩了!
});
正确姿势(安全第一):
fetchData()
.then(data =>console.log(data))
.catch(error => {
console.error('捕获错误:', error);
// 还可以在这里做错误恢复操作
});
3. 用 Promise.all() 同时处理多个任务 🚀
需要等三个请求都完成?别一个个等!
// 三个不相关的请求,可以同时进行!
const [user, orders, notifications] = awaitPromise.all([
fetchUser(),
fetchOrders(),
fetchNotifications()
]);console.log('所有数据都拿到了!');
注意:只要有一个失败,整个 Promise.all 就失败!如果希望即使有失败也继续,可以用 Promise.allSettled()。
4. 别忘了 Promise.race() 竞速赛 🏎️
设置超时控制:
// 如果fetchData超过5秒没响应,就报超时错误
const timeout = newPromise((_, reject) => {
setTimeout(() => reject(newError('请求超时')), 5000);
});const data = awaitPromise.race([
fetchData(),
timeout
]);
5. 善用 async/await 让代码更清晰 ✨
then 链看着晕? 试试 async/await:
// before: then链
functiongetUserData() {
return getUser()
.then(user => getOrders(user.id))
.then(orders => getDetails(orders[0].id));
}// after: async/await
asyncfunctiongetUserData() {
try {
const user = await getUser();
const orders = await getOrders(user.id);
const details = await getDetails(orders[0].id);
return details;
} catch (error) {
console.error('获取数据失败:', error);
throw error; // 重新抛出错误
}
}
6. 避免在循环中滥用 await 🔄
错误示范(一个个等,慢死了):
// 这样要等10秒!
for (const id of ids) {
const data = await fetchItem(id); // 等完一个再下一个
}
正确姿势(一起请求,快多了):
// 这样只要等1秒!
const promises = ids.map(id => fetchItem(id));
const results = awaitPromise.all(promises);
7. 合理处理错误,别一棍子打死 🎯
精细化错误处理:
try {
const user = await getUser();
const orders = await getOrders(user.id);
} catch (error) {
if (error.type === 'USER_NOT_FOUND') {
// 用户不存在,跳转到登录页
redirectToLogin();
} elseif (error.type === 'NETWORK_ERROR') {
// 网络问题,显示重试按钮
showRetryButton();
} else {
// 其他错误,通用处理
showErrorMessage('系统繁忙,请稍后再试');
}
}
8. 用 Promise 化改造回调函数 🔄
遇到回调函数?把它包装成 Promise:
// 传统的回调函数
functionoldSchoolMethod(data, callback) {
// 一些异步操作...
}// 包装成 Promise
functionmodernMethod(data) {
returnnewPromise((resolve, reject) => {
oldSchoolMethod(data, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
}
// 现在可以愉快地用了!
const result = await modernMethod(data);
总结表格
记住这些技巧,你的 Promise 代码就能从「勉强能用」升级到「优雅高效」!🚀