Promise 核心知识点(非基础)

大家好,我是有一点想法的thinkmars,目前在准备面试与工作,借着间隙时间学习复习,写一点基础文章,欢迎想找工作的人与我一起学习,一起讨饭吃~


Promise的出现是异步编程的革命,自问世以后,前端再也离不开它。

一、Promise 执行机制核心原理

  1. Event Loop 与微任务队列

    • Promise 回调属于微任务(Microtask),与宏任务(Macrotask)的区别
    • 代码执行顺序分析:setTimeout vs Promise.then() 的执行优先级
    • 示例分析:console.log(1); Promise.resolve().then(()=>console.log(2)); console.log(3);
  2. Promise 链式调用原理

    • then() 方法返回新 Promise 的规则:
      • 返回普通值 → 触发新 Promise 的 resolve
      • 返回 Promise → 直接继承其状态
      • 抛出错误 → 触发新 Promise 的 reject
    • 链式调用中断场景分析:中间某个 then() 抛出错误如何传递?

二、Promise 状态流转与代码路径

  1. 状态变化关键逻辑

    • resolve() 触发后,后续 then() 中的回调进入微任务队列
    • reject() 触发后,优先寻找最近的 catch()then(onFulfilled, onRejected) 的第二个参数
    • 状态固化后不可变:即使再次调用 resolve/reject 无效
  2. 代码路径分析(高频考题)

    javascript 复制代码
    new Promise((resolve, reject) => {
      console.log(1);
      resolve(2);
      console.log(3);
    })
    .then(val => {
      console.log(val);
      return val * 2;
    })
    .then(val => {
      console.log(val);
      throw new Error('test');
    })
    .catch(err => {
      console.log(err.message);
      return 100;
    })
    .then(val => console.log(val));
    • 输出顺序分析:1 → 3 → 2 → 4 → 'test' → 100
    • 关键点:同步代码立即执行,then/catch 回调异步执行

三、错误处理关键技巧

  1. catch 的穿透性

    • 错误会沿着链式调用传递,直到被 catch 捕获
    • 示例:若中间某个 then() 没有错误处理,错误会跳过后续 then() 的第一个参数
  2. reject 的两种写法

    • 显式调用 reject()
    • 抛出异常:throw new Error('msg')(等同于 reject
  3. 全局异常捕获

    • window.addEventListener('unhandledrejection', callback) 处理未捕获的 Promise 错误

四、高阶 API 使用场景

  1. Promise.all vs Promise.allSettled

    • all: 全部成功时返回结果数组,任一失败立即拒绝
    • allSettled: 始终等待所有 Promise 完成,返回状态描述对象
    • 适用场景对比(如批量请求是否允许部分失败)
  2. Promise.race 竞速场景

    • 第一个完成的 Promise 决定结果(无论成功/失败)

    • 超时控制实战代码:

      javascript 复制代码
      const timeout = (ms) => 
        new Promise((_, reject) => 
          setTimeout(() => reject(new Error('Timeout')), ms)
        );
      
      Promise.race([fetchData(), timeout(3000)])
        .then(data => console.log(data))
        .catch(err => console.log(err));
  3. Promise.any(ES2021)

    • 第一个成功的 Promise 决定结果,全部失败时抛出 AggregateError

五、常见陷阱与面试题

  1. 嵌套 Promise 问题

    • 反模式:在 then() 中嵌套 new Promise(应使用链式调用扁平化)
  2. 值穿透(Value Penetration)

    javascript 复制代码
    Promise.resolve(1)
      .then(Promise.resolve(2))  // 参数不是函数!
      .then(console.log);        // 输出 1
    • 原因:then() 的参数必须为函数,否则发生值穿透
  3. 同步代码中的错误

    javascript 复制代码
    new Promise((resolve, reject) => {
      throw new Error('sync error');  // 同步错误直接触发 reject
    }).catch(err => console.log(err));

六、Async/Await 与 Promise 的关系

  1. 本质是语法糖

    • async 函数返回 Promise,await 相当于 then() 的链式调用
    • 错误处理:try/catch 捕获 await 后的 Promise reject
  2. 执行顺序对比

    • 分析 async/await 与普通 Promise 链的微任务队列差异

七、实战代码分析训练

  1. 混合宏任务/微任务执行顺序

    javascript 复制代码
    setTimeout(() => console.log(1), 0);
    Promise.resolve().then(() => console.log(2));
    console.log(3);
    // 输出顺序:3 → 2 → 1
  2. 复杂链式调用+错误处理

    javascript 复制代码
    Promise.resolve()
      .then(() => { throw new Error('err1'); })
      .catch(() => console.log('catch1'))
      .then(() => console.log('then1'))
      .catch(() => console.log('catch2'));
    // 输出:catch1 → then1
相关推荐
To_OC4 小时前
LC 51 N 皇后:我以为难的是回溯,结果栽在了对角线下标
javascript·算法·leetcode
不好听6134 小时前
从一行 JSX 到屏幕像素:前端开发者必须懂的浏览器渲染管线
前端
恒拓高科WorkPlus4 小时前
企业级内网即时通讯建设模型:BeeWorks内网IM四层架构
前端
前端小李子5 小时前
前端环境变量裸奔?我用 EnvShield 给它穿了件防弹衣
前端
youtootech5 小时前
HarmonyOS《柚兔学伴》项目实战25-我的页面、Web 嵌入与项目总结
前端·华为·harmonyos
触底反弹5 小时前
🔥 2026 大模型选择指南:别再只看 Benchmark 了,这些维度才是关键!
人工智能·面试
小林ixn5 小时前
从零到一理解 React 父子组件通信:手写一个 Todo 应用带你彻底搞懂单向数据流
前端·javascript·react.js
醇氧7 小时前
CountDownLatch / CyclicBarrier / Semaphore 面试高频问答清单
前端·面试·职场和发展
窝子面8 小时前
手搓最简前后端协作-node
javascript·数据库