🐸 青蛙编程网
首页 / 前端 / AJAX / 5. async/await 与错误处理

async/await 与错误处理

这是什么:async/await = Promise 的语法糖:await 让你用同步的写法等异步结果,async 标记「这个函数里要用 await」。

为什么用:请求一多,.then 就开始套娃——then 里面再 fetch 再 then,链条越拉越长。async/await 把「等数据」写成像普通赋值一样自然,代码量砍半,还有 try/catch 这个熟悉的错误处理。

如何用:把第 2 章的两段式请求重写成 await 风格,加上加载状态和统一错误兜底,凑齐实战三件套。

重写第 2 章的请求

两段式 vs await 版,感受一下:

// 两段式(第 2 章写法)
fetch('https://jsonplaceholder.typicode.com/posts/1')
  .then(res => res.json())
  .then(data => console.log(data.title))

// async/await 版
async function loadPost() {
  let res = await fetch('https://jsonplaceholder.typicode.com/posts/1')
  let data = await res.json()
  console.log(data.title)
}
loadPost()

你会看到:两个版本打印同样的标题。await 版读起来就像「发请求,等响应;拆包,等数据」——每一步等完再走下一步,但页面照样不卡(异步的本质没变)。

部件 作用
async function 标记这个函数里可以使用 await
await 等右边的 Promise 出结果,拿到值再往下走
函数返回值 async 函数自身返回 Promise,外部要拿结果还是 .then 或 await 它

注意:await 必须写在 async 函数里(或 <script type="module"> 顶层),直接在普通 script 里写会报错。

try/catch:同步写法的错误兜底

两段式的错误走 .catch,await 版走 try/catch——和 JSON 教程里 safeParse 的套路一模一样:

async function loadPost() {
  try {
    let res = await fetch('https://jsonplaceholder.typicode.com/posts/1')
    if (!res.ok) throw new Error('HTTP ' + res.status)   // 404/500 自己抛
    let data = await res.json()
    console.log('标题:', data.title)
  } catch (err) {
    console.error('请求失败:', err.message)   // 网络错误 + 主动抛的错都进这里
  }
}

ok 自查 + try/catch 就是 await 时代的标准错误处理模板,.catch 的职责全由 catch 块接管。

加载状态:让用户知道「在跑了」

请求要花时间,界面上要有「加载中…」的反馈,结束时关掉——finally 是收尾的最佳位置:

async function loadUsers() {
  let box = document.getElementById('app')
  box.textContent = '加载中…'                     // ① 开始:亮出加载态
  try {
    let res = await fetch('https://jsonplaceholder.typicode.com/users?_limit=3')
    if (!res.ok) throw new Error('HTTP ' + res.status)
    let users = await res.json()
    box.innerHTML = users.map(u => `<div>${u.name}</div>`).join('')
  } catch (err) {
    box.textContent = '加载失败:' + err.message   // ② 失败:友好提示
  } finally {
    console.log('请求流程结束(无论成败都执行)')   // ③ 收尾:关 loading、恢复按钮
  }
}
loadUsers()

你会看到:先显示「加载中…」,数据到了换成三个用户名;若断网则显示失败原因。finally 在成败两种情况下都会执行,适合放「关闭加载动画、把提交按钮恢复可点」这类收尾活。

三个小坑

  1. await 只在 async 函数里有效——写在普通函数或全局会直接 SyntaxError
  2. await 的是 Promise——await fetch(...) 对,写成 await res.json(没加括号)拿到的是函数不是数据
  3. 循环里别轻易 await——for 循环里 await 会一个接一个排队等;并发请求用 Promise.all([...]) 一次全等齐

记忆口诀:async 配 await,异步写成同步味;try 抓错 finally 收,加载状态别浪费。

📝 本章小结

  • async/await 用同步风格写异步:await 等 Promise 出结果,代码顺序即执行顺序
  • await 必须在 async 函数里;async 函数自己也返回 Promise
  • 错误处理用 try/catch,res.ok 自查照旧;finally 负责收尾
  • 实战三件套:加载态 + ok 自查 + try/catch,缺一不可

动手改

  1. 把第 4 章的 POST 请求重写成 async/await 版
  2. 给 loadUsers 加个「重新加载」按钮,请求期间把它设为 disabled,finally 里恢复
  3. 用 Promise.all 同时请求 /posts/1 和 /users/1,一起拿到结果

上一章:POST 提交数据 · 下一章:综合练习 🐸

📥 下载本章代码

ZIP 内含本章全部代码文件与说明,解压即用,与教程内容同步生成。