async函数中处理并发请求需区分场景:promise.all用于互不依赖的并行请求,总耗时≈最慢请求;promise.allsettled适用于容错并行,逐项判断状态;大批量请求须限制并发数(如p-limit),避免压垮服务;切忌for循环内直接await导致串行。

在 async 函数中处理并发请求,核心是让多个异步操作真正“同时发起”,而不是一个接一个等。关键不是写多少个 await,而是控制执行时机和错误韧性。
用 Promise.all 并行发起独立请求
当几个接口互不依赖(比如同时拉用户信息、订单列表、通知数),直接用 Promise.all 最简洁高效:
- 所有请求在调用瞬间就发出,总耗时≈最慢那个请求的耗时
- 返回数组,按顺序对应每个请求的结果
- 注意:只要有一个失败,整个
Promise.all就 reject,需统一捕获
示例:
async function loadHomeData() {
try {
const [user, orders, notifications] = await Promise.all([
fetch('/api/user').then(r => r.json()),
fetch('/api/orders').then(r => r.json()),
fetch('/api/notifications').then(r => r.json())
]);
return { user, orders, notifications };
} catch (err) {
console.error('任一请求失败', err);
throw err;
}
}
用 Promise.allSettled 处理“容错并行”
如果某些请求失败不能影响整体流程(比如统计类接口挂了不影响主功能),Promise.allSettled 更合适:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 不管成功失败,全部等完才返回;每项带
status字段标识状态 - 可逐项判断:成功取
value,失败读reason - 无需外层 try/catch,错误已结构化封装
示例:
async function loadDashboard() {
const results = await Promise.allSettled([
fetch('/api/analytics').then(r => r.json()),
fetch('/api/recent-posts').then(r => r.json()),
fetch('/api/ads-config').then(r => r.json())
]);
const data = {};
results.forEach((res, i) => {
if (res.status === 'fulfilled') {
data[`item${i}`] = res.value;
} else {
console.warn(`第${i}项加载失败`, res.reason);
data[`item${i}`] = null; // 或设默认值
}
});
return data;
}
控制最大并发数,避免压垮服务
面对几十个请求(如批量查 100 个商品价格),不能全扔给 Promise.all —— 可能触发限流或超时。需要限制同一时间最多发 N 个:
- 手动实现:维护一个执行中 Promise 数组,用
Promise.race等最早完成的,腾出位置再塞新请求 - 更推荐:用成熟工具,如
p-limit库,一行代码搞定 - 自定义函数里,记得用
await Promise.all(executing)确保全部结束
简版逻辑示意:
async function concurrentFetch(urls, limit = 3) {
const executing = [];
const results = [];
for (const url of urls) {
const p = fetch(url).then(r => r.json());
executing.push(p);
results.push(p);
if (executing.length >= limit) {
await Promise.race(executing); // 等最快的一个完成
executing.splice(executing.indexOf(await p), 1); // 清理已结束的
}
}
return Promise.all(results);
}
避免常见性能陷阱
并发 ≠ 盲目堆 await,几个易忽略点:
- 别在 for 循环里直接 await —— 那是串行,不是并发
- 不用 try/catch 包裹每个 await,除非真要单独处理每个错误;否则优先用
.catch()给单个 Promise 设 fallback 值 - 对重复请求做缓存(比如相同参数的 API 调用),比并发更重要
- 后端支持的话,优先合并接口(如用 GraphQL 或聚合 API),减少请求数本身
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










