在async函数中应根据任务依赖性、资源约束和错误容忍度灵活选择并发或串行:独立任务用Promise.all/allSettled并发执行,有依赖关系则用await串行,复杂场景可混合使用限流池实现并发+串行组合。

在 async 函数中灵活控制并发与串行,关键不是“非此即彼”,而是根据任务依赖性、资源约束和错误容忍度,主动选择执行模式。同一段逻辑里混用两者很常见,比如先并发拉取数据,再串行处理结果。
明确任务关系:先判断再选策略
不需要硬记语法,先问三个问题:
- 这些任务是否相互独立?能同时发请求而不打架 → 适合并发
- 后一步是否必须等前一步输出(比如 token 换取用户信息)→ 必须串行
- 失败一个要不要中断全部?要 → 用 Promise.all;不中断 → 用 Promise.allSettled
并发执行:用 Promise.all 或 allSettled 控制“一起出发”
适用于无依赖的批量操作,如并行加载多个 API:
async function loadUserProfile() {
const [user, posts, settings] = await Promise.all([
fetch('/api/user'),
fetch('/api/posts'),
fetch('/api/settings')
]);
return { user, posts, settings };
}
注意:Promise.all 一失败就中断;若允许部分失败,改用 Promise.allSettled,并手动过滤结果:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
const results = await Promise.allSettled([
fetch('/api/a'),
fetch('/api/b'),
fetch('/api/c')
]);
const fulfilled = results
.filter(r => r.status === 'fulfilled')
.map(r => r.value);
串行执行:用 await 逐个等待,自然保持顺序
适合有数据流转或强时序要求的场景,例如分步提交表单:
- 先调用验证接口
- 再上传文件(需验证通过后才触发)
- 最后保存元数据(依赖上传返回的 URL)
async function submitForm(data) {
const valid = await checkValidity(data);
if (!valid) throw new Error('校验失败');
const uploadRes = await uploadFile(data.file);
const metaRes = await saveMetadata({ ...data, url: uploadRes.url });
return metaRes;
}
混合控制:并发 + 串行 + 限流,应对真实业务
实际项目常需组合使用。例如:从 ID 列表批量获取用户详情,但最多同时发起 3 个请求(防压垮服务),每个请求成功后再做本地加工:
- 用 async-pool(推荐)或手写限流函数管理并发池
- 每个任务内部仍可用 await 做串行子步骤
// 使用 async-pool(轻量、稳定、支持动态控流)
import asyncPool from 'async-pool';
const ids = [1, 2, 3, 4, 5, 6];
const results = await asyncPool(3, ids, async id => {
const res = await fetch(`/api/user/${id}`);
const data = await res.json();
return processUserData(data); // 串行处理本条数据
});
⚠️ 手写限流要注意:别传已执行的 Promise(如 fetch()),而应传工厂函数(如 () => fetch()),否则请求在分批前就发出去了。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










