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

1. Promise 核心特性

  • 本质:解决 JS 异步回调地狱的异步编程方案,代表一个异步操作的最终完成(或失败)及其结果值。
  • 三种状态(不可逆)

    表格

    状态 描述 触发条件
    pending(等待) 初始状态,未完成也未失败 Promise 刚创建时
    fulfilled(成功) 异步操作完成 调用 resolve () 方法
    rejected(失败) 异步操作失败 调用 reject () 方法
    ✅ 关键:状态一旦从 pending 变为 fulfilled/rejected,永久不可变更

2. 核心方法

表格

方法 作用
then() 接收成功 / 失败回调,返回新 Promise,支持链式调用;第一个参数处理成功,第二个可选参数处理失败
catch() 专门处理失败状态(等价于 then (null, rejectCb)),捕获链式调用中任意环节的错误
finally() 无论成功 / 失败都会执行,不接收状态参数,返回新 Promise,用于清理操作(如关闭加载弹窗)

3. 链式调用核心

  • then/catch/finally 均返回新的 Promise 实例,新实例的状态由回调函数的执行结果决定:
    1. 回调返回普通值 → 新实例状态为 fulfilled,值为该普通值;
    2. 回调返回 Promise → 新实例状态与该 Promise 一致;
    3. 回调抛出错误 → 新实例状态为 rejected,值为抛出的错误。

二、手写 Promise 基本用法(40 分钟必练)

案例 1:基础 Promise 封装异步操作

js

// 封装异步请求(模拟接口调用)
function requestData(url) {
  // 创建Promise实例
  return new Promise((resolve, reject) => {
    // 模拟异步操作(如axios请求)
    setTimeout(() => {
      const random = Math.random();
      if (random > 0.5) {
        // 成功:修改状态为fulfilled,传递结果
        resolve({ code: 200, data: `数据-${url}` });
      } else {
        // 失败:修改状态为rejected,传递错误
        reject(new Error(`请求${url}失败`));
      }
    }, 1000);
  });
}

// 基本使用:then+catch
requestData("/api/user")
  .then((res) => {
    console.log("请求成功:", res);
    // 链式调用:返回新值,供下一个then接收
    return res.data + "-处理后";
  })
  .then((processedData) => {
    console.log("链式处理结果:", processedData);
    // 链式调用:返回新Promise
    return requestData("/api/order");
  })
  .then((orderRes) => {
    console.log("订单请求成功:", orderRes);
  })
  .catch((err) => {
    // 捕获任意环节的错误
    console.log("请求失败:", err.message);
  })
  .finally(() => {
    // 无论成败都执行(如关闭加载)
    console.log("请求结束,关闭加载弹窗");
  });

案例 2:catch 捕获错误的两种方式对比

js

// 方式1:then的第二个参数(仅捕获当前Promise错误)
requestData("/api/test").then(
  (res) => console.log(res),
  (err) => console.log("then捕获:", err)
);

// 方式2:catch(捕获链式调用所有错误,推荐)
requestData("/api/test")
  .then((res) => {
    // 这里抛出错误也会被catch捕获
    throw new Error("手动抛出错误");
  })
  .catch((err) => console.log("catch捕获:", err));

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

面试题:Promise 的状态有哪些?如何理解 Promise 的链式调用?

标准答案(高级工程师视角,精简且有深度)
1. Promise 的三种核心状态

Promise 有且仅有三种状态,且状态一旦变更不可逆

  • pending(等待):初始状态,异步操作未完成;
  • fulfilled(已成功):异步操作完成,通过 resolve() 触发,状态不可回退;
  • rejected(已失败):异步操作失败,通过 reject() 或抛出错误触发,状态不可回退。

补充:ES6 规范中 Promise 状态为 “排他性”,同一 Promise 无法同时处于成功 / 失败状态,这是保证异步结果唯一性的核心。

2. Promise 链式调用的核心逻辑

Promise 的链式调用依赖 then/catch/finally 方法的返回值特性—— 这三个方法均返回新的 Promise 实例,而非原实例,新实例的状态由回调函数执行结果决定:

  1. 若回调返回普通值(非 Promise / 错误):新 Promise 状态为 fulfilled,值为该普通值;
  2. 若回调返回另一个 Promise:新 Promise 状态与该 Promise 完全同步(状态 + 结果);
  3. 若回调抛出错误:新 Promise 状态为 rejected,值为抛出的错误。
3. 实际开发中的价值(面试加分)
  • 解决回调地狱:将嵌套的异步回调(如多层接口请求)转为线性链式调用,代码可读性提升 80%+;
  • 错误统一捕获:catch 可捕获链式调用中任意环节的错误,避免每层异步都写错误处理;
  • 异步流程标准化:Promise 是 async/await 的底层基础,也是前端异步方案(如 axios、fetch)的核心封装方式。
4. 避坑点(体现工程化思维)
  • 链式调用中若未写 catch,未捕获的错误会触发 unhandledrejection 全局事件,导致页面报错;
  • finally 不改变 Promise 状态,仅做收尾操作,其返回值不会影响后续链式调用。

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

表格

错题类型 错误代码 / 场景 错误原因 正确思路 / 知识点
状态理解偏差 认为 resolve 后可再调用 reject 修改状态 忽略 Promise 状态不可逆特性 状态一旦变更,后续 resolve/reject 无效
链式调用错误 链式调用中未 return 值,下一个 then 接收 undefined 忘记 then 回调返回值会传递给下一个 then 需 return 需要传递的数据 / Promise
错误捕获遗漏 仅用 then 第二个参数捕获错误 无法捕获 then 回调内抛出的错误 优先用 catch 统一捕获链式错误

总结

  1. 核心考点:Promise 状态的 “不可逆性” 和链式调用的 “返回新实例” 规则,是异步编程的核心基础;
  2. 实战重点:熟练用 Promise 封装异步操作,掌握 catch 统一错误处理,为后续学 async/await 打基础;
  3. 易错点:忽略链式调用的 return 传递规则、未捕获异步错误,开发中需养成 “必写 catch” 的习惯。
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐