前端JS: Promise

7 阅读3分钟

Promise 核心要点

一、核心概念

三种状态

  1. pending(进行中)
  2. fulfilled(已成功)
  3. rejected(已失败)

状态不可逆:一旦改变就不能再变

二、基本使用

创建 Promise

const promise = new Promise((resolve, reject) => {
  if (成功) resolve(value)
  else reject(error)
})

实例方法

  1. .then(onFulfilled, onRejected) ​ - 处理成功/失败
  2. .catch(onRejected) ​ - 捕获错误
  3. .finally(onFinally) ​ - 最终执行(不接收参数)

三、重要静态方法

1. Promise.all([p1, p2, ...])

  • 全部成功才成功,一个失败立即失败
  • 返回值:按顺序的结果数组
  • 使用场景:并发请求,全部完成后处理

2. Promise.allSettled([p1, p2, ...])

  • 等待所有完成(无论成功失败)
  • 返回值:包含状态和结果的对象数组
  • 使用场景:需要知道所有结果

3. Promise.race([p1, p2, ...])

  • 第一个完成的决定结果(无论成功失败)
  • 使用场景:超时控制、竞速

4. Promise.any([p1, p2, ...])

  • 任意一个成功就成功,全部失败才失败
  • 使用场景:多个备用方案

5. Promise.resolve(value)

  • 创建已成功的 Promise
  • 如果传入 Promise,则直接返回

6. Promise.reject(reason)

  • 创建已失败的 Promise

四、核心特性

1. 链式调用

promise
  .then(value => { /* 处理 */ })
  .then(value => { /* 继续处理 */ })
  .catch(error => { /* 错误处理 */ })

2. 错误冒泡

  • 错误会一直传递,直到被 .catch()捕获
  • .catch()返回的 Promise 可以继续链式调用

3. 微任务(Microtask)

  • Promise 回调是微任务
  • 执行时机:当前同步代码执行完 → 微任务 → 宏任务(如 setTimeout)

五、面试高频问题

Q1: Promise 的三种状态?

  • pending(进行中)
  • fulfilled(已成功)
  • rejected(已失败)
  • 状态一旦改变就不可逆

Q2: Promise.all 和 Promise.allSettled 的区别?

方法成功条件失败条件结果
Promise.all全部成功一个失败就失败结果数组
Promise.allSettled全部完成不失败,返回所有结果状态对象数组

Q3: 如何取消一个 Promise?

  • 原生 Promise 无法取消

  • 常见方案:

    1. 使用 AbortController(配合 fetch)
    2. 包装 Promise,提供取消方法
    3. 使用 Promise.race 实现超时取消

Q4: Promise 的错误处理方式?

  1. .catch()方法
  2. .then()的第二个参数
  3. try/catch配合 async/await
  4. 全局的 unhandledrejection事件

Q5: async/await 和 Promise 的关系?

  • async函数返回 Promise
  • await后面跟 Promise,会等待其完成
  • async/await是 Promise 的语法糖,使异步代码更像同步

Q6: 什么是宏任务和微任务?

  • 宏任务:setTimeout、setInterval、I/O
  • 微任务:Promise.then/catch/finally、MutationObserver
  • 执行顺序:同步代码 → 微任务 → 宏任务

Q7: Promise.race 的使用场景?

// 超时控制
Promise.race([
  fetch('/api'),
  new Promise((_, reject) => 
    setTimeout(() => reject(new Error('超时')), 5000)
  )
])

Q8: 如何实现 Promise 的链式调用?

  • .then()返回新的 Promise
  • 每个 .then()可以返回:值、Promise、thenable 对象
  • 错误会跳过中间的 .then(),直到被 .catch()捕获

六、常见考点

1. 执行顺序题

console.log(1)
setTimeout(() => console.log(2), 0)
Promise.resolve().then(() => console.log(3))
console.log(4)
// 输出:1, 4, 3, 2

2. 错误处理题

Promise.reject('error')
  .then(() => console.log('then1'))
  .catch(err => console.log('catch1:', err))  // 执行
  .then(() => console.log('then2'))           // 执行
  .catch(err => console.log('catch2:', err))  // 不执行

3. 状态变化题

const p = new Promise((resolve, reject) => {
  resolve(1)
  reject(2)  // 无效,状态已改变
  resolve(3) // 无效
})

七、一句话总结

Promise 是异步编程的解决方案,通过状态管理和链式调用解决了回调地狱问题,配合 async/await 使异步代码更易读写。


面试回答示例

面试官:请简述 Promise 的特性

回答

"Promise 是 ES6 引入的异步编程解决方案,主要有三个特点:

  1. 有三种状态:pending、fulfilled、rejected,状态一旦改变不可逆
  2. 支持链式调用,解决了回调地狱问题
  3. 错误可以通过 catch 统一捕获,支持错误冒泡

常用的静态方法有:

  • Promise.all:全部成功才成功
  • Promise.race:第一个完成的决定结果
  • Promise.allSettled:等待所有完成
  • Promise.any:任意一个成功就成功

Promise 的回调是微任务,执行时机在同步代码之后、宏任务之前。"