Skip to content

C16. 异步编程 async/await

6.1. 🌟 async 标记的异步函数返回 Promise 对象

async 关键词将函数标记为“异步函数”,其返回值始终是一个 Promise 对象。

javascript
// 普通函数 vs 异步函数对比
function normalFunc() {
  return "普通结果"; // 直接返回值
}

async function asyncFunc() {
  return "异步结果"; // 等价于 Promise.resolve("异步结果")
}

asyncFunc().then(result => console.log(result)); // "异步结果"

async 特性

  • 自动包装返回值:任何返回值会被自动包裹为 Promise.resolve(value)
  • 错误自动包装:函数内部抛出的错误会转为 Promise.reject(error)
  • 只能在函数前使用async 仅修饰函数定义

6.2. ⭐ 异步函数中 await 表达式可直接获取 Promise 内部值

await 关键字暂停函数执行,直到 Promise 完成,直接获取其成功值。

javascript
async function fetchData() {
  const response = await fetch("https://api.example.com/data"); // 等待响应
  const data = await response.json(); // 等待解析 JSON
  console.log(data); // 直接使用数据
}

fetchData();

核心规则

  1. await 只能在 async 函数内使用
  2. 暂停的是当前函数的执行,不会阻塞主线程
  3. 等待期间代码控制权返回浏览器

6.2.1. 简化 Promise 链式调用

javascript
// 传统 Promise 写法
fetch("https://api.example.com")
  .then(response => response.json())
  .then(data => console.log(data));

// async/await 写法
async function simplifiedFetch() {
  const response = await fetch("https://api.example.com");
  const data = await response.json();
  console.log(data);
}

6.3. 🌟 await 将异常 Promise 对象直接抛出

如果 Promise 被拒绝(reject),await抛出错误,需用 try/catch 捕获。

javascript
async function errorDemo() {
  try {
    const response = await fetch("https://api.example.com/404");
    if (!response.ok) throw new Error("HTTP错误"); // 自定义错误
    const data = await response.json();
  } catch (error) {
    console.error("捕获到错误:", error.message); // 直接处理错误
  }
}

errorDemo();

错误处理要点

  • 必须用 try/catch 包裹可能出错的 await 表达式
  • 未捕获的 await 错误会冒泡到全局(如浏览器控制台报错)
  • 可以链式 catch
    javascript
    myAsyncFunc()
      .catch(error => console.log("最终错误处理"));

知识回顾

  1. 核心语法关系
    • async 函数 → 返回 Promise
    • await 解包 Promise 的值或错误
  2. 关键特性
    • 代码更接近同步风格(避免嵌套 .then
    • 错误通过 try/catch 集中处理
    • 保持非阻塞特性(不会卡住主线程)
  3. 使用限制
    • await 必须在 async 函数内
    • 同步代码不能直接 await
  4. 陷阱提醒
    • 忽略错误处理导致程序崩溃
    • 在循环中滥用 await 可能降低性能
    • Promise 链与 async/await 可混合使用

课后练习

  1. (单选)以下哪个是合法的 async 函数定义?

    • A. async function getData() { return fetch(...) }
    • B. function async getData() { ... }
    • C. await fetch("https://api.com"); (非函数内)
    • D. A和C都对
  2. (填空)在 async 函数中,使用______关键字等待异步操作完成。

  3. (代码纠错)修复以下代码,使错误被捕获:

    javascript
    async function brokenFunc() {
      await fetch("https://invalid-url").then(data => console.log(data));
    }
    // 错误:未处理网络错误
  4. (操作题)重写 C15 中的 POST 表单提交案例,使用 async/await 替代 .then/catch:

    • 显示加载状态
    • 成功时显示“登录成功”
    • 错误时显示具体提示(如网络问题/账号错误)

备注: (1) 通过对比传统 Promise 和 async/await 代码,突出语法优势 (2) 错误处理部分需强调 try/catch 的必要性 (3) 操作题要求综合运用 async/await 和 DOM 操作

Built by Vitepress | Apache 2.0 Licensed