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
相关推荐
waterHBO16 分钟前
直接从图片生成 html
前端·javascript·html
EndingCoder27 分钟前
JavaScript 时间转换:从 HH:mm:ss 到十进制小时及反向转换
javascript
互联网搬砖老肖1 小时前
React组件(一):生命周期
前端·javascript·react.js
我科绝伦(Huanhuan Zhou)1 小时前
深入解析Shell脚本编程:从基础到实战的全面指南
前端·chrome
小马哥编程1 小时前
React和Vue在前端开发中, 通常选择哪一个
前端·vue.js·react.js
aklry1 小时前
uniapp实现在线pdf预览以及下载
前端·pdf·uni-app
HCl+NaOH=NaCl+H_2O1 小时前
Quasar组件 Carousel走马灯
javascript·vue.js·ecmascript
℘团子এ1 小时前
vue3中预览Excel文件
前端·javascript
shmily麻瓜小菜鸡2 小时前
在 Angular 中, `if...else if...else`
前端·javascript·angular.js
bloglin999992 小时前
npm和nvm和nrm有什么区别
前端·npm·node.js