Vue中文社区

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);

总结表格

技巧
什么时候用
好处
链式调用
多个依赖的异步操作
避免回调地狱
.catch()
所有 Promise
防止程序崩溃
Promise.all()
多个独立异步操作
大幅提升速度
Promise.race()
需要超时控制
避免无限等待
async/await
复杂异步逻辑
代码更清晰
循环优化
处理数组异步操作
提升性能
精细错误处理
需要不同错误策略
更好用户体验
Promise 化
处理回调函数
统一代码风格

记住这些技巧,你的 Promise 代码就能从「勉强能用」升级到「优雅高效」!🚀