async/await 实现顺序执行异步操作的核心是用 await 逐个等待 promise,确保后一个任务在前一个完成后才开始;错误写法如并发发起请求需避免,正确方式是 for...of + await 或 promise.all 保序处理。

使用 async 和 await 实现顺序执行异步操作,核心在于让每个异步任务等待前一个完成后再开始,避免并发竞争或结果错乱。关键不是“强行串行”,而是自然地用 await 暂停函数执行,等 Promise 解析后再继续。
用 await 逐个等待 Promise
最直接的方式:在 async 函数中,对每个返回 Promise 的操作依次 await。JavaScript 会自动按书写顺序等待,不需额外控制逻辑。
- 每个
await后的表达式必须返回 Promise(或可转换为 Promise 的值) - 如果某个 await 抛出错误,后续语句不会执行,可配合 try/catch 捕获
- 示例:依次获取用户信息、订单列表、订单详情
async function loadUserData() {
try {
const user = await fetch('/api/user').then(r => r.json());
const orders = await fetch(`/api/orders?uid=${user.id}`).then(r => r.json());
const detail = await fetch(`/api/order/${orders[0]?.id}`).then(r => r.json());
return { user, orders, detail };
} catch (err) {
console.error('加载失败', err);
}
}
避免无意中的并发执行
容易出错的是:把多个异步调用写在同级,没加 await,导致它们同时发起(并发),而非顺序执行。
- ❌ 错误写法:
const a = fetch(...); const b = fetch(...);—— 这两个请求立刻并发发出 - ✅ 正确写法:
const a = await fetch(...); const b = await fetch(...);—— b 等 a 完成后才发起 - 若需“先发请求,再按序处理响应”,可先创建 Promise,再 await 它们(但仍是顺序等待)
处理数组中的顺序异步操作
遍历数组并顺序执行异步操作(如逐条保存数据),不能直接用 forEach 或 map,因为它们不等待 Promise。
- 用
for...of循环 +await最清晰可靠 - 避免
array.map(async () => {...}),它返回 Promise 数组,但不会按序等待 - 示例:顺序上传多个文件
async function uploadFiles(files) {
for (const file of files) {
await fetch('/upload', {
method: 'POST',
body: file
});
}
console.log('全部上传完成');
}
需要并发但结果要按序时怎么办
有时业务要求“并发发起请求”,但最终结果必须严格按输入顺序排列(比如渲染列表)。这时不能靠 await 顺序执行,而要用 Promise.all 配合索引保持顺序。
- 用
map创建 Promise 数组,每个 Promise 包含原始索引或标识 -
await Promise.all(promises)并发执行,结果数组顺序与输入一致 - 适用于“快”且“顺序重要”的场景,和纯顺序执行目的不同
async function loadInOrder(urls) {
const promises = urls.map((url, index) =>
fetch(url).then(r => r.json()).then(data => ({ index, data }))
);
const results = await Promise.all(promises);
return results.sort((a, b) => a.index - b.index).map(r => r.data);
}











