promise await详解

264 阅读2分钟

promise await

首先抛出两个个问题

1. 什么时候使用promise await

当我们的代码里面需要依赖一个异步结果的返回时就可以使用await,但是最近发现的代码中,很多同学在每个函数调用前都加一个 await。这会导致很严重的性能问题,因为大多数时候,一条语句并不依赖于其之前的那条语句,但是你加上await 导致还是必须等待之前的语句执行完毕。

2. 怎么用才是正确的使用方式

在使用Promise.all 的时候大家会有几个误区:

1.执行顺序和打印顺序一致吗?

2.其中一个promise出错后,如何捕获到异常呢?

先来看第一个问题

  const funA = () => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('this is funA')
        resolve()
      }, 1000)
    })
  }
  
  const funB = () => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('this is funB')
        resolve()
      }, 1000)
    })
  }
  
  const funC = () => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('this is funC')
        resolve()
      }, 1000)
    })
  }

  Promise.all([funA(), funB(), funC()]).then((res) = >{ 
    console.log(res)
  })

Promise.all 执行的过程是并行的 执行顺序是根据执行的快慢来决定的,打印顺序是按照Promise.all在数组里面的调用顺序来决定的

所以 如果你的需求是不关心执行顺序 只关注返回结果的情况 可以使用Promise.all

但是如果对执行顺序有强烈要求 可以使用 await

await会阻塞函数执行,promise的resolve返回值会作为await的结果,才会执行后面的语句。如果reject就不执行后面的语句

第二个问题

在promise队列中,使用map来过滤每一个promise,在任意一个报错后抛出异常,p.catch方法返回值会被promise.resolve()包裹,这样传入到promise.all()中 数据都是resolved状态的,确保了每个promise都能走到then里面

    let p1 = new Promise((resolve, reject) => {
      resolve({
        code: 200,
        list: []
      });
    });
 
    let p2 = new Promise((resolve, reject) => {
      resoLve({
        code: 200,
        list: []
      });
    });
 
    let p3 = new Promise((resolve, reject) => {
      reject({
        code: 500,
        msg: "服务异常"
      });
    });
    
    Promise.all([p1, p2, p3].map(p => p.catch(e => e)))
      .then(res => {
        console.log(res);
        /*
        打印结果:
        {code: 200, list: Array(0)}
        {code: 200, list: Array(0)}
        {code: 500, msg:”服务异常”}
        */
      }).catch(err => {
        console.log(err);
      })