语法

Promise.all() 实现并发同步接收返回值

应用场景描述(你需要同时调多个接口的数据,并在前端对数据进行处理,这就需要等待所有接口返回数据后才能操作。)

在日常项目应用中你是否碰到过这种情况:在加载某一个模块数据的时候,出于性能考虑(或某些不知名原因),后端给过来的接口有好几个,而我们需要都执行一遍才能得到我们想要的数据(散装接口)。这时候,如果几个接口数据比较小还好,我们可以一路 await 下去,或者用then嵌套,但是如果数据比较多,那等待时间可能就有点长了,对于界面渲染就不太友好了(可能卡一个地方好几秒)。那么这时候有办法在他们异步发送请求的同时,能在某一个地方获取到他们的数据,这不就节省了我大量时间么(这不正是我早上赶时间想要的效果么,边上厕所边刷牙(狗头)...,3分钟出门)Promise.all()  就能做到这一点。

介绍(来自于MDN):

Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,并且只返回一个Promise实例, 那个输入的所有promise的resolve回调的结果是一个数组。这个Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。它的reject回调执行是,只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。

 MDN网站的demo

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});
// expected output: Array [3, 42, "foo"]

自己些了个小例子测试了一下 看时间上到底有没有提升

普通接口调用写法 或者 使用es6的 async/await 异步转同步

//   function Index() {
//       普通调用嵌套写法
//       console.time()
//       const p1 = new Promise((resolve, reject) => {
//         console.log('这里是p1')
//         setTimeout(() => {
//           resolve('这里是p1的返回')
//         }, 1000)
//       }).then((r1) => {
//         new Promise((resolve, reject) => {
//           console.log('这里是p2')
//           setTimeout(() => {
//             resolve('这里是p2的返回')
//           }, 1000)
//         }).then((r2) => {
//           console.log(r1)
//           console.log(r2)
//           console.timeEnd()
//         })
//       }) 
//     }

//异步转同步
async function Index2() {
      console.time()
      const p1 =await new Promise((resolve, reject) => {
        console.log('这里是p1')
        setTimeout(() => {
          resolve('这里是p1的返回')
        }, 1000)
      })
      const p2 =await new Promise((resolve, reject) => {
        console.log('这里是p2')
        setTimeout(() => {
          resolve('这里是p2的返回')
        }, 1000)
      })
      console.log(p1)
      console.log(p2) 
      console.timeEnd()
   }
    //Index();
    Index2();

打印结果,差不多2s, 一步一步执行下来

js axios请求捕获异常 js获取异步请求数据_错误信息

 使用Promise.all()来实现调用

async function Index() {
      console.time()
      const p1 = new Promise((resolve, reject) => {
        console.log('这里是p1')
        setTimeout(() => {
          resolve('这里是p1的返回')
        }, 1000)
      })
      const p2 = new Promise((resolve, reject) => {
        console.log('这里是p2')
        setTimeout(() => {
          resolve('这里是p2的返回')
        }, 1000)
      })
      Promise.all([p1, p2]).then((val) => {
        console.log(val)
        console.timeEnd()
      })
       //当然也可以使用 async/await写法
       /*   
        const p = await Promise.all([p1, p2])
        console.log(p);
        console.timeEnd(); 
        */
       //补充说明:如果我们的接口已经套上了一层 promise 便已经实现了同时执行异步的条件
       //下面这种写法耗时和Promise.all也是一样的,但是嵌套多了可能代码就不太优雅了
       /*  p1.then((r1) => {
        p2.then((r2) => {
          console.log(r1)
          console.log(r2)
          console.timeEnd()
        })
      }) */
        
    }
    Index()

打印结果,差不多1s 时间

js axios请求捕获异常 js获取异步请求数据_ajax_02

 当然 Promise.all()  成功回调时间已最长的接口返回时间为准,如果把 p2的 定时改成 2s 那么回调也会在2s之后打印输出

js axios请求捕获异常 js获取异步请求数据_js axios请求捕获异常_03

 总结

在需要同时发送多个请求且需要都执行成功才能去渲染界面时,我们便可以使用Promise.all() 来节省我们的请求时间,提升性能。

更多方法:

静态方法

介绍说明

Promise.all(iterable)

     这个方法返回一个新的promise对象,该promise对象在iterable参数对象里所有的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则立即触发该promise对象的失败。这个新的promise对象在触发成功状态以后,会把一个包含iterable里所有promise返回值的数组作为成功回调的返回值,顺序跟iterable的顺序保持一致;如果这个新的promise对象触发了失败状态,它会把iterable里第一个触发失败的promise对象的错误信息作为它的失败错误信息。Promise.all方法常被用于处理多个promise对象的状态集合。(可以参考jQuery.when方法---译者注)

Promise.allSettled(iterable)

等到所有promises都已敲定(settled)(每个promise都已兑现(fulfilled)或已拒绝(rejected))。

返回一个promise,该promise在所有promise完成后完成。并带有一个对象数组,每个对象对应每个promise的结果。

Promise.any(iterable)

接收一个Promise对象的集合,当其中的一个 promise 成功,就返回那个成功的promise的值。

Promise.race(iterable)

当iterable参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象。

Promise.reject(reason)

返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法

Promise.resolve(value)

返回一个状态由给定value决定的Promise对象。如果该值是thenable(即,带有then方法的对象),返回的Promise对象的最终状态由then方法执行决定;否则的话(该value为空,基本类型或者不带then方法的对象),返回的Promise对象状态为fulfilled,并且将该value传递给对应的then方法。通常而言,如果您不知道一个值是否是Promise对象,使用Promise.resolve(value) 来返回一个Promise对象,这样就能将该value以Promise对象形式使用。

    

参考

MDN 关于 Promise.all()

更多使用相关可参考

MDN 关于 Promise

完了。