Day6 完整学习包(async/await)——2026 0318

一、核心知识点(30 分钟吃透)

1. async/await 核心本质

  • async/awaitPromise 的语法糖,底层完全基于 Promise 实现,目的是将异步代码写成 "同步风格",彻底摆脱回调嵌套和链式调用的冗余。
  • 核心规则:
    1. async 修饰函数:函数返回值自动包装为 Promise(即使返回普通值,也会变成 fulfilled 状态的 Promise);
    2. await 只能在 async 函数内使用:暂停函数执行,等待右侧 Promise 状态变更(成功 / 失败),再恢复执行并返回 Promise 的结果;
    3. 错误处理:await 后的 Promise 失败时,需用 try/catch 捕获(否则会导致整个 async 函数返回 rejected 状态的 Promise)。

2. 与 Promise 对比

表格

特性 Promise 链式调用 async/await
代码风格 链式 then/catch,线性但冗余 同步风格,可读性更高
错误处理 统一 catch 捕获 try/catch 捕获(更符合直觉)
流程控制 多层嵌套需链式传递 可直接用 if/for 等同步逻辑

二、实战练习:封装 async/await 版请求(40 分钟必练)

案例 1:基础封装(兼容成功 / 失败)

js

复制代码
// 1. 封装基础请求函数(返回Promise)
function request(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const mockData = { code: 200, data: `请求${url}成功` };
      // 模拟50%成功率
      Math.random() > 0.5 
        ? resolve(mockData) 
        : reject(new Error(`请求${url}失败`));
    }, 1000);
  });
}

// 2. async/await 封装业务请求(同步风格)
async function fetchData() {
  // 加载状态(如显示loading)
  console.log("请求中...");
  try {
    // 暂停执行,等待请求结果
    const userRes = await request("/api/user");
    console.log("用户数据:", userRes);

    // 基于上一个请求结果,发起下一个请求(同步逻辑更直观)
    const orderRes = await request(`/api/order?userId=${userRes.data.id || 1}`);
    console.log("订单数据:", orderRes);

    return { user: userRes, order: orderRes }; // 返回值自动包装为Promise
  } catch (err) {
    // 捕获任意await的错误
    console.error("请求失败:", err.message);
    // 错误兜底(可选)
    return { code: 500, msg: "请求异常" };
  } finally {
    // 无论成败,关闭加载
    console.log("请求结束,关闭loading");
  }
}

// 3. 调用async函数(返回Promise,可链式调用)
fetchData().then(res => console.log("最终结果:", res));

案例 2:批量请求(Promise.all + async/await)

js

复制代码
// 并行请求多个接口,等待所有请求完成
async function fetchBatchData() {
  try {
    // 并行执行,总耗时取最长的请求(而非串行叠加)
    const [userRes, goodsRes, orderRes] = await Promise.all([
      request("/api/user"),
      request("/api/goods"),
      request("/api/order")
    ]);
    console.log("批量请求结果:", { userRes, goodsRes, orderRes });
  } catch (err) {
    console.error("任意一个请求失败:", err);
  }
}
fetchBatchData();

三、核心面试题 + 标准答案(20 分钟背会)

面试题:async/await 的原理是什么?相比 Promise 有哪些优点?

标准答案(高级工程师视角,精简且有深度)
1. async/await 的底层原理
  • async/awaitGenerator 函数 + Promise 的语法糖 (ES7 引入),由 JS 引擎自动实现 Generator 的执行器逻辑:
    1. async 函数:本质是返回一个 Promise 的 Generator 函数的语法糖,函数执行时会自动创建迭代器并执行;
    2. await 关键字:等价于 Generator 中的 yield,暂停函数执行,等待右侧 Promise 状态变更后,将结果作为 yield 的返回值,恢复函数执行;
    3. 错误处理:底层复用 Promise 的错误捕获机制,await 后的 Promise 失败会触发 try/catch,本质是捕获 Promise 的 rejected 状态。
2. async/await 相比 Promise 的核心优点
  • 代码可读性极致提升:将异步代码从 "链式 then/catch" 转为 "同步风格",尤其是多层异步嵌套(如接口依赖请求),代码逻辑更直观,维护成本降低 50%+;
  • 流程控制更灵活:可直接使用 if/for/while 等同步流程控制语句(如 "请求 A 成功才请求 B,否则终止"),而 Promise 链式调用需通过 return 控制,逻辑冗余;
  • 错误处理更符合直觉 :用 try/catch 捕获单个 / 多个异步错误,可精准控制错误范围(如仅捕获某一个 await 的错误),而 Promise 链式调用的 catch 会捕获所有环节错误,需额外区分;
  • 调试更友好 :断点可直接停在 await 行,同步调试异步代码,而 Promise 链式调用需在 then 回调内断点,调试体验差。
3. 实战避坑点(面试加分)
  • await 会阻塞当前 async 函数执行,非必要时不要串行请求(如无依赖的多接口请求,用 Promise.all 并行执行,提升性能);
  • 未用 try/catch 包裹的 await 错误,会导致 async 函数返回 rejected 状态的 Promise,需全局捕获(如 window.addEventListener('unhandledrejection', cb));
  • await 右侧不仅可以是 Promise,也可以是普通值(直接返回该值),但实际开发中仅用于 Promise 等待。

四、错题整理模板(10 分钟完成)

表格

错题类型 错误代码 / 场景 错误原因 正确思路 / 知识点
串行请求性能问题 无依赖的多接口依次 await 忽略并行请求优化 用 Promise.all 并行执行无依赖请求
错误捕获遗漏 async 函数内未写 try/catch await 失败导致函数返回 rejected Promise 必须用 try/catch 捕获,或外部 catch
语法错误 普通函数内使用 await 忽略 await 仅能在 async 函数内使用 给外层函数添加 async 修饰

总结

  1. 核心考点:async/await 是 Promise 的语法糖,底层基于 Generator + Promise,核心优势是 "同步风格写异步";
  2. 实战重点 :掌握 try/catch 错误处理、Promise.all 并行请求优化,这是前端接口封装的核心技能;
  3. 易错点:避免无意义的串行 await、不要遗漏错误捕获,这是面试中体现工程化思维的关键。
相关推荐
SameX2 小时前
我做了个本地优先的 iOS 足迹 App,上架后才发现:最难的根本不是地图,而是让轨迹活下来
前端
想你依然心痛2 小时前
教育数字化:ONLYOFFICE在在线课堂与协作学习中的一站式解决方案
学习·onlyoffice·平台·在线学习
踩着两条虫2 小时前
AI 驱动的 Vue3 应用开发平台 深入探究(十八):扩展与定制之集成第三方库
前端·vue.js·agent
css趣多多2 小时前
# Vue 3 `<script setup>` 中变量声明的正确姿势:何时必须使用 `ref()`?
前端·javascript·vue.js
稽稽稽稽不如人2 小时前
《从零开始的java从入门到入土的学习生活——JavaWeb后端篇》Chapter18——JavaWeb后端篇学习记录——AOP 面向切面编程
java·学习·生活
sjg200104142 小时前
GoFrame学习随便记4(待续)
学习
用户69371750013842 小时前
跟你唠唠!A2A协议来了,谁能拿下下一代手机系统的主动权?
android·前端·人工智能
踩着两条虫2 小时前
AI 驱动的 Vue3 应用开发平台 深入探究(十七):扩展与定制之扩展 Provider 系统
前端·vue.js·agent