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
相关推荐
小小小小宇10 分钟前
前端XSS和CSRF以及CSP
前端
UFIT14 分钟前
NoSQL之redis哨兵
java·前端·算法
超级土豆粉21 分钟前
CSS3 的特性
前端·css·css3
星辰引路-Lefan22 分钟前
深入理解React Hooks的原理与实践
前端·javascript·react.js
wyn2000112833 分钟前
JavaWeb的一些基础技术
前端
江城开朗的豌豆42 分钟前
JavaScript篇:函数间的悄悄话:callee和caller的那些事儿
javascript·面试
Hygge-star1 小时前
Flask音频处理:构建高效的Web音频应用指南
前端·flask·音视频·pygame·csdn开发云
江城开朗的豌豆1 小时前
JavaScript篇:回调地狱退散!6年老前端教你写出优雅异步代码
前端·javascript·面试
飞鸟malred1 小时前
vite+tailwind封装组件库
前端·react.js·npm
TE-茶叶蛋1 小时前
Vue Fragment vs React Fragment
javascript·vue.js·react.js