用 async/await 配合 fetch 实现串行请求的核心是依次 await 每个 fetch 及其响应解析,确保前序完成后再发起后续请求,从而避免竞态、保证顺序、提升可读性与错误可控性。

用 async/await 配合 fetch 实现串行请求,核心是让每个请求等待前一个完成后再发起,避免竞态、保证顺序,同时保持代码可读和错误可控。
用 await 逐个等待 fetch 调用
这是最直接、最清晰的方式:把多个 fetch 写在 async 函数里,用 await 依次执行。每个请求天然阻塞后续逻辑,自然形成串行。
示例:
async function fetchInSeries() {
try {
const res1 = await fetch('/api/user');
const user = await res1.json();
const res2 = await fetch(`/api/posts?userId=${user.id}`);
const posts = await res2.json();
const res3 = await fetch(`/api/stats?postId=${posts[0]?.id}`);
const stats = await res3.json();
return { user, posts, stats };
} catch (err) {
console.error('请求链失败:', err);
throw err;
}
}
✅ 优点:逻辑线性、调试友好、错误定位明确。
⚠️ 注意:没有并发,适合强依赖场景(如后一个 URL 需前一个响应里的 ID)。
封装通用串行工具函数
如果多个地方需要串行调用,可抽象为一个接收 fetch 函数数组的工具:
立即学习“Java免费学习笔记(深入)”;
async function series(fetchFns) {
const results = [];
for (const fn of fetchFns) {
const res = await fn();
results.push(await res.json());
}
return results;
}
// 使用
series([
() => fetch('/api/a'),
() => fetch('/api/b'),
() => fetch('/api/c')
]).then(data => console.log(data));
? 提示:传入的是函数而非直接调用,确保按需执行;也可扩展支持自定义解析逻辑(如 text()、arrayBuffer())。
处理部分失败但继续后续请求(可选策略)
有时希望即使某步失败也不中断整个流程(比如日志上报不关键),可用 catch 局部捕获:
async function fetchWithGrace() {
const user = await (await fetch('/api/user')).json();
let posts = null;
try {
posts = await (await fetch(`/api/posts?uid=${user.id}`)).json();
} catch (e) {
console.warn('获取 posts 失败,跳过', e);
}
let stats = null;
try {
stats = await (await fetch(`/api/stats`)).json();
} catch (e) {
console.warn('获取 stats 失败,跳过', e);
}
return { user, posts, stats };
}
避免常见陷阱
-
不要忘记 await 响应体方法:fetch 返回的是
Response对象,.json()、.text()等也是 Promise,必须await,否则得到的是 pending Promise。 -
不要在循环中无 await 地调用 fetch:写成
fetch(...).then(...)会并发,不是串行。 -
超时控制需手动加:fetch 本身不支持 timeout,可用
AbortController或包装 Promise.race。 -
错误要主动抛出或处理:fetch 只在网络错误时 reject,HTTP 4xx/5xx 仍 resolve,需检查
res.ok。


















