避不开的Promise,那咱们搞懂它

2,081 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

说到ES6,就一定会提到Promise,Promise是我们从初级程序员上升到中级程序员一个必须掌握的东西,它里面的 .all.race 方法,今天来做一个总结!

promise.all 方法

先看看MDN上的解释:

 Promise.all(iterable) 方法返回一个Promise实例,此实例在iterable参数内所有的promise都完成(resolved)或参数中不包含promise时回调完成(resolve);如果参数中promise有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败promise的结果。

翻译解释一下:Promise.all() 将多个Promise放在一个数组中,当整个数组的全部promise成功时才会返回成功,当数组中的promise有一个出现失败时就返回失败 (失败的原因是第一个失败promise的结果)。

我们用代码来演示一下

  let p1 = new Promise((resolve, reject) => {
    // Promise的状态只能通过resolve和reject决定,一旦确定状态不能够被修改
    setTimeout(() => reject('p1的状态是失败'), 2000)
  })
  
  let p2 = new Promise((resolve, reject) => {
    setTimeout(() => resolve('p2的状态是成功'), 1000)
  })
  
   Promise.all([p1, p2])
    .then((resolve, reject) => {
      // 用.then处理成功的状态回调
      console.log(resolve, 1111)
      // .catch捕获错误的状态
    })
    .catch(reject => console.log(reject, 2222))
 

image.png

这里我故意把p2的计时器时间写成1秒,这样p2的状态会先回来,结果我们发现.all最后结果走的还是.catch,说明.all是当整个数组的全部promise成功时才会返回成功,当数组中的promise有一个出现失败时就返回失败 (失败的原因是第一个失败promise的结果)。

然后我们在.all里传入两个状态为fulfilled的Promise, 来看看结果

 let p2 = new Promise((resolve, reject) => {
    setTimeout(() => resolve('p2的状态是成功'), 1000)
  })
  
   let p4 = new Promise((resolve, reject) => {
    setTimeout(() => resolve('p4的状态是成功'), 1000)
  })
  
  // 此时传入p2和p4
  Promise.all([p2, p4])
    .then((resolve, reject) => {
      // 用.then处理成功的状态回调
      console.log(resolve, 1111)
      // .catch捕获错误的状态
    })
    .catch(reject => console.log(reject, 2222))

image.png

通过浏览器打印就可以看到,当.all数组里传入的Promise状态都为fulfilled的时候,返回的是一个数组,数组里的每一项就是每个Promise中resolve抛出的值

promise.race 方法

先看看MDN上的解释:

Promise.race()  函数返回一个 Promise,它将与第一个传递的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失败(rejects),这要取决于第一个完成的方式是两个中的哪个。

简单解释一下:race含有赛跑的意思,将多个Promise放在一个数组中,数组中有一个promise最先得到状态结果,不管是完成(fulfilled)还是失败(Rejected) , 那么这个 .race 方法就会返回这个状态结果。

代码演示一下

   let p1 = new Promise((resolve, reject) => {
    // Promise的状态只能通过resolve和reject决定,一旦确定状态不能够被修改
    setTimeout(() => reject('p1的状态是失败'), 2000)
  })
  
  let p2 = new Promise((resolve, reject) => {
    setTimeout(() => resolve('p2的状态是成功'), 500)
  })
  
  let p3 = new Promise((resolve, reject) => {
    setTimeout(() => reject('p3的状态是失败'), 3000)
  })
  
  let p4 = new Promise((resolve, reject) => {
    setTimeout(() => resolve('p4的状态是成功'), 1000)
  })
  
  Promise.race([p1, p2, p3, p4])
    .then((resolve, reject) => {
      // 用.then处理成功的状态回调
      console.log(resolve, 1111)
      // .catch捕获错误的状态
    })
    .catch(reject => console.log(reject, 2222))

image.png

因为p2的计时器时间是500毫秒,p2的状态会先得到是fulfilled,所以.race得到的状态就是fulfilled,然后.then接收p2resolve的回调。