详解JavaScript中Promise类的使用方法

作者:半夏

时间:2026-10-26

浏览:146

本文详解JavaScript中Promise类的四个静态方法:all、allSettled、race和any。通过具体代码示例,解析各方法的执行逻辑、结果返回格式及异常处理机制,帮助开发者根据业务需求选择合适的方法。

文章目录

本文主要介绍Promise类方法的实际应用场景。关于Promise的基础用法,此处不再展开,此前已有文章详细阐述过Promise的核心逻辑实现。尽管Promise在日常开发中应用广泛,但随着ES11和ES12的发布,新增了两个相关语法特性。本文将简要说明这些新特性的用法,内容相对简单。

1. all

Promise.all方法接收一个数组作为参数,数组中可以包含多个Promise对象。该方法会等待所有传入的Promise状态都变为fulfilled(成功)后,才获取最终结果。最终结果是一个数组,其中包含了每个Promise resolve的值,且结果的顺序与传入数组中Promise的顺序保持一致,与执行时间无关。

const p1 = new Promise((resolve, reject) => {
  const obj = { data: '11111' }
  setTimeout(() => {
    resolve(obj)
  }, 3000)
})
 
const p2 = new Promise((resolve, reject) => {
  const obj = { data: '22222' }
  setTimeout(() => {
    resolve(obj)
  }, 2000)
})
 
const p3 = new Promise((resolve, reject) => {
  const obj = { data: '33333' }
  setTimeout(() => {
    resolve(obj)
  }, 1000)
})
 
Promise.all([p1, p2, p3]).then(result => {
  console.log(result)
}).catch(err => {
  console.log('err:', err)
})

上述代码将在3秒后,在then方法中获取到最终结果,具体如下:

1. all

然而,all方法存在一个缺陷:如果数组中有一个Promise变为rejected(失败)状态,新返回的Promise会立即变为对应的reject状态。这意味着错误只能在catch中捕获,其他已经fulfilled状态的Promise的值将无法获取。因此,allSettled方法应运而生。

2. allSettled

allSettled是ES11(2020年)新增的API,即Promise.allSettled。

该方法会在所有Promise都有结果时(无论是fulfilled还是rejected),都会在then方法中返回最终结果:

const p1 = new Promise((resolve, reject) => {
  const obj = { data: '11111' }
  setTimeout(() => {
    resolve(obj)
  }, 3000)
})
 
const p2 = new Promise((resolve, reject) => { 
  const obj = { data: '22222' }
  setTimeout(() => {
    reject(obj)
  }, 2000)
})
 
const p3 = new Promise((resolve, reject) => {
  const obj = { data: '33333' }
  setTimeout(() => {
    resolve(obj)
  }, 1000)
})
 
Promise.allSettled([p1, p2, p3]).then(result => {
  console.log(result)
}).catch(err => {
  console.log('err:', err)
})

示例中传入了三个Promise,在2秒时p2变为rejected状态。即便如此,我们依然可以拿到结果,但result数组的结构有所变化,具体打印结果如下:

1. all

从打印结果可以看出,allSettled返回的是一个数组,数组中的每个元素对应一个Promise的结果对象。该对象包含status状态属性,以及对应的value值。

3. race

race意为竞技或赛跑,即谁先有结果就采用谁的结果。因此,result获取到的不是一个数组,而是最快resolve的那个Promise的结果值。

const p1 = new Promise((resolve, reject) => {
  const obj = { data: '11111' }
  setTimeout(() => {
    resolve(obj)
  }, 3000)
})
 
const p2 = new Promise((resolve, reject) => { 
  const obj = { data: '22222' }
  setTimeout(() => {
    resolve(obj)
  }, 2000)
})
 
const p3 = new Promise((resolve, reject) => {
  const obj = { data: '33333' }
  setTimeout(() => {
    resolve(obj)
  }, 1000)
})
 
Promise.race([p1, p2, p3]).then(result => {
  console.log(result)
}).catch(err => {
  console.log('err:', err)
})

控制台打印结果如下:

1. all

由于p3用时最短,因此result获取到的是p3 resolve出的结果值。但如果最快的Promise是reject状态呢?我们来看下面的情况:

const p1 = new Promise((resolve, reject) => {
  const obj = { data: '11111' }
  setTimeout(() => {
    resolve(obj)
  }, 3000)
})
 
const p2 = new Promise((resolve, reject) => { 
  const obj = { data: '22222' }
  setTimeout(() => {
    reject('出错了~~~')
  }, 500)
})
 
const p3 = new Promise((resolve, reject) => {
  const obj = { data: '33333' }
  setTimeout(() => {
    resolve(obj)
  }, 1000)
})
 
Promise.race([p1, p2, p3]).then(result => {
  console.log(result)
}).catch(err => {
  console.log('err:', err)
})

修改代码,将p2的时间设置为0.5秒,且状态为rejected。再次查看打印结果:

1. all

结果会直接被catch捕获。这表明,如果最快的Promise状态为rejected,后续其他Promise的resolve值将无法获取。如果我们希望获取最快的fulfilled状态的值,即忽略前面的reject状态,继续等待下一个resolve,该如何实现?这就引出了any方法。

4. any

const p1 = new Promise((resolve, reject) => {
  const obj = { data: '11111' }
  setTimeout(() => {
    resolve(obj)
  }, 3000)
})
 
const p2 = new Promise((resolve, reject) => { 
  const obj = { data: '22222' }
  setTimeout(() => {
    reject('出错了~~~')
  }, 500)
})
 
const p3 = new Promise((resolve, reject) => {
  const obj = { data: '33333' }
  setTimeout(() => {
    resolve(obj)
  }, 1000)
})
 
Promise.any([p1, p2, p3]).then(result => {
  console.log(result)
}).catch(err => {
  console.log('err:', err)
})

沿用之前的代码,将方法改为any,再次查看打印结果:

1. all

我们在1秒后获取到p3 resolve的结果,而p2的reject状态被忽略。那么,如果所有Promise都是rejected状态,它会如何处理?我们来看:

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('出错了111~~~')
  }, 3000)
})
 
const p2 = new Promise((resolve, reject) => { 
  setTimeout(() => {
    reject('出错了222~~~')
  }, 500)
})
 
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('出错了333~~~')
  }, 1000)
})
 
Promise.any([p1, p2, p3]).then(result => {
  console.log(result)
}).catch(err => {
  console.log('err:', err, err.errors)
})

打印结果如下:

1. all

此时会进入catch分支,并打印出错误信息。其中,err.errors属性中包含了各个Promise reject传递的错误信息,err是内部封装的错误提示。

至此,关于JavaScript中Promise类使用方法的介绍到此结束。如需了解更多JavaScript Promise相关内容,请搜索本站历史文章或继续浏览相关文章。感谢大家的支持!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章