async/await不能直接简化fetch本身,但能彻底改变异步请求逻辑的组织方式;需显式调用.json()等方法、检查response.ok、用try/catch捕获错误,并推荐封装为健壮的api函数。

async/await 不能直接简化 fetch 本身,但能彻底改变你组织异步请求逻辑的方式——它让错误处理、链式依赖和条件分支变得可读、可控、可调试。
为什么不能直接用 await fetch() 就完事?
fetch 返回的是 Promise,await 确实能等它 resolve,但关键点在于:fetch 只有网络失败(如断网、DNS 错误)才会 reject;HTTP 状态码 404、500 等依然会 resolve,且返回一个 Response 对象,不是你要的 JSON 数据。
常见错误现象:
- 写了 await fetch('/api/user') 却没调 .json(),结果拿到的是 Response 对象,控制台打印是 Response {…},取 .data 报错
- 没检查 response.ok,后端返回 500 时代码仍往下执行,导致 .json() 解析空体或异常内容而 throw
实操建议:
- 每次
await fetch()后必须显式调用.json()、.text()或.blob(),且它们也返回 Promise,要再await - 务必检查
if (!response.ok) throw new Error(...),否则 4xx/5xx 不会进入catch - 不要省略
try/catch——await的 Promise reject 会直接抛出,不捕获就崩
怎么写一个健壮的 async 请求函数?
封装成函数才能复用,也方便统一加 loading、错误日志、token 注入。重点不是“简写”,而是把重复判断收拢。
示例(带基础错误处理):
async function apiGet(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
}
使用场景:
- 单个请求:直接
const data = await apiGet('/api/posts'); - 多个并行请求:
const [a, b] = await Promise.all([apiGet('/a'), apiGet('/b')]); - 串行依赖:
const user = await apiGet('/user'); const posts = await apiGet(`/posts?uid=${user.id}`);
async/await 和 .then() 在错误传播上有什么实质区别?
区别在堆栈和可调试性。用 .then().catch() 时,错误堆栈里看不到原始调用位置;而 async/await 抛出的错误,堆栈指向 await 那一行,和同步代码一样直观。
容易踩的坑:
- 在
for循环里直接await多个请求 → 实际是串行,性能差;想并行得用Promise.all() - 忘记给
async函数加try/catch,错误向上冒泡到未处理的 promise rejection,浏览器报Uncaught (in promise) -
await后面跟了非 Promise(比如普通对象),不会报错但也不会“等待”,容易误以为异步生效了
要不要在 fetch 里加 signal: AbortController?
要,尤其在用户可能快速切换页面、取消操作的场景(比如搜索框输入防抖、表单提交中点击返回)。否则请求还在后台跑,内存和连接没释放,还可能触发过期的 setState 导致 React warning。
实操建议:
- 每次发请求前新建
const controller = new AbortController(); - 传入
fetch(url, { signal: controller.signal }) - 在组件卸载或取消时调用
controller.abort()(React 中可在useEffect清理函数里做) - 注意:
abort()会让fetchPromise reject,错误类型是AbortError,需单独判断避免混进业务错误
真正难的从来不是写对 async/await 语法,而是决定什么时候 abort、怎么分类错误、是否重试、loading 状态如何与多个并发请求对齐——这些没法靠语法糖解决,得靠封装边界和明确约定。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











