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
相关推荐
weisian1511 分钟前
基础篇--概念原理-3-向量是什么?——从原理到实战,一篇讲透
面试·职场和发展·向量
iCxhust5 分钟前
在 emu8086 中可以直接编译运行的完整汇编程序,演示数组的定义、遍历、求和、求最大值。
开发语言·前端·javascript·汇编·单片机·嵌入式硬件·算法
JianZhen✓9 分钟前
2026前端高频面试题总结(Vue/JS/网络/Webpack/性能优化/手写)
前端·javascript·vue.js
里欧跑得慢13 分钟前
Flutter 主题管理:构建一致的用户界面
前端·css·flutter·web
龙猫里的小梅啊27 分钟前
CSS(八)CSS显示模式display属性
前端·css·css3
逻辑驱动的ken28 分钟前
Java高频面试考点场景题22
java·开发语言·jvm·面试·职场和发展·求职招聘·春招
雨季mo浅忆30 分钟前
第二项目重新梳理
前端·面试
星光开发者30 分钟前
基于springboot电动汽车租赁管理系统-计算机毕设 附源码 11217
javascript·spring boot·mysql·django·php·html5·express
李白的天不白39 分钟前
webpack 与 vue-loader 版本冲突问题
前端·vue.js·webpack
拾光Ծ41 分钟前
【Linux系统】进程信号(上)
linux·运维·服务器·面试·信号处理