Promise 核心机制与常用方法详解

作者:异步漫步时间:2026-10-23 08:56:29浏览:308

本文系统梳理 JavaScript 中 Promise 的核心用法,详细解析 then、catch、finally 链式调用的状态传递机制,以及 Promise.all 和 Promise.race 的组合策略。同时涵盖 Promise.resolve 与 Promise.reject 的转换规则,帮助开发者掌握异步处理的最佳实践。

Promise 基础链式调用:then、catch 与 finally

then

在 then 方法中,可以通过 return 语句返回另一个 Promise 对象。


const p1 = new Promise((resolve, reject) =>{
  resolve('p1')
})
const p2 = new Promise((resolve, reject) =>{
 setTimeout(() =>{
  resolve('p2')
 },3000)
})
p1.then(res => {
 console.log(res)
  return p2
}).then(res =>{ 
  // p2 resolve后才执行
  console.log(res)
})
//p1
// 3s后输出...
// p2

此时,当前 Promise(如 p1)的状态将被新返回的 Promise(如 p2)所取代。只有当这个新的 Promise(p2)状态发生修改后,链式调用中的下一个 then 才会执行。

catch

1. 作用

catch 方法用于捕获 Promise 执行过程中抛出的错误,其功能等同于调用 .then(null, rejection) 或 .then(undefined, rejection)。

2. 可以获取到的错误

首先,它可以捕获 Promise 构造函数内部直接抛出的错误。需要注意的是,如果在 Promise 已经 resolve 之后才抛出错误,则该错误不会被 catch 捕获。


const p1 = new Promise((resolve,reject) => {throw new Error('error')})
p1.catch(error => console.log(error))  // Error: error

其次,它也能处理 Promise 显式调用 reject 操作时传递的错误。


const p2 = new Promise((resolve,reject) => reject('rejected'))
p2.catch(error => console.log(error)) // rejected

此外,如果 then 方法的回调函数中抛出了错误,catch 同样可以捕获到。


const p3 = new Promise((resolve,reject) => resolve('resolved'))
p3.then(res =>{
  throw new Error('error')
}).catch(error => console.log(error)) // Error: error

最后,如果 then 方法返回了一个新的 Promise(且该链中未定义 catch 方法),而新 Promise 内部发生了 reject 或抛出错误,这些错误也会被当前的 catch 捕获。

3. 推荐使用 catch 方式捕获错误,而不是 then 的第二个参数:

主要原因是 catch 能够捕获到它前面所有 then 方法中发生的错误,而 then 的第二个参数仅能捕获紧邻的前一个 then 的错误,覆盖范围有限。

finally

  • 无论 Promise 最终状态是 fulfilled 还是 rejected,finally 中的操作都会执行。
  • finally 方法不接受参数,因此无法直接获取当前 Promise 的最终状态值。

Promise 组合方法:all 与 race

Promise.all

1. 参数

Promise.all 的参数不仅可以是数组,任何具有 Iterator 接口的对象都可以作为参数传入。如果参数是数组,其每个元素都应为 Promise 实例;如果不是,则会通过 Promise.resolve 将其转换为 Promise 实例。


const obj = {
  [Symbol.iterator]() {
    let index = 0
    return {
      next() {
        return {
          // promise对象 和 其他类型都可以
          value: new Promise(resolve => resolve(index++)), done: index > 2
          // value: index++, done: index > 2
        }
      }
    }
  }
}
const p = Promise.all(obj)
p.then(res => {
  console.log(res) // [0, 1]
}) 

2. 状态


const p = Promise.all([p1, p2, p3]);

Promise.all 返回的 Promise(p)的状态取决于所有传入的 Promise(如 p1、p2、p3)的状态,具体分为两种情况:

  • 只有当 p1、p2、p3 的状态全部变为 fulfilled 时,p 的状态才会变为 fulfilled。此时,p1、p2、p3 的返回值会组成一个数组,传递给 p 的回调函数。
  • 只要 p1、p2、p3 中有一个实例被 rejected,p 的状态就会立即变为 rejected。此时,第一个被 reject 的实例的返回值,会传递给 p 的回调函数。

3. catch

如果参数中的某个 Promise 已经定义了 catch 方法,那么 Promise.all() 自身的 catch 将不会捕获到该错误。

Promise.race

  • 只要 p1、p2、p3 中有一个实例率先改变状态,p 的状态就会随之改变。那个率先改变的 Promise 实例的返回值,将传递给 p 的回调函数。
  • Promise.race 的参数要求和 catch 规则与 Promise.all 相同。

Promise 静态转换方法:resolve 与 reject

Promise.resolve

该方法用于将现有对象转换为 Promise 对象。

1. 参数

  • 如果参数是一个 Promise 实例,Promise.resolve 将原封不动地返回这个实例。
  • 如果参数是一个 thenable 对象(即具有 then 方法的对象),Promise.resolve 会将其转换为 Promise 对象,并立即执行它的 then 方法。
  • 如果参数不是 thenable 对象,或者是一个原始值,Promise.resolve 会返回一个新的 Promise 对象,其状态为 resolved。
  • 如果 Promise.resolve 没有参数,它将直接返回一个处于 resolved 状态的 Promise 对象。

Promise.reject

该方法返回一个状态为 rejected 的 Promise 实例。

Promise.reject() 方法的参数会原封不动地作为 reject 的理由,并作为后续错误处理方法的参数传递。


const thenable = {
 then(resolve, reject) {
  reject('error');
 }
};

Promise.reject(thenable)
.catch(e => {
 console.log(e === thenable)
})
// true e并不是'error'

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章