前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >javascript异步之Promise.all()、Promise.race()、Promise.finally()

javascript异步之Promise.all()、Promise.race()、Promise.finally()

作者头像
陌上寒
发布2019-04-02 15:09:05
2.3K0
发布2019-04-02 15:09:05
举报
文章被收录于专栏:前端进阶前端进阶

今天我们继续讨论promise 网络上关于PromiseAPI使用的文章多如牛毛,为了保持javascript异步系列文章的完整性,现在对promise的API进行简单全面的介绍

准备工作

我在easy-mock添加了三个接口,备用

依然使用axios进行ajax请求

Promise.all()

Promise.all()有点像“并行” 我们看一个栗子

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>promise</title>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>

<body>
  <script>
    {
      const p1 = axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise1')
        .then(({
          data
        }) => {
          console.log('p1成功啦');
          return data.data
        })

      const p2 = axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise2')
        .then(({
          data
        }) => {
          console.log('p2成功啦');
          return data.data
        })

      const p3 = axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/mock')
        .then(({
          data
        }) => {
          console.log('p3成功啦');
          return data.data
        })

      const p = Promise.all([p3, p1, p2])
        .then(arr => {
          console.log(arr);
          console.log('Promise.all成功啦');   
        })
        .catch(err=>{
          console.log(err,'Promise.all错啦');
        })
    }
  </script>
</body>

</html>

我们知道axios返回的是一个promise对象,我们可以看下

代码语言:javascript
复制
 console.log(p1);

Promise.all就是用于将多个 Promise 实例,包装成一个新的 Promise 实例 Promise.all,接收一个数组作为参数,数组的每一项都返回Promise实例 我们重点看这段代码

代码语言:javascript
复制
     const p = Promise.all([p3, p1, p2])
        .then(arr => {
          console.log(arr);
          console.log('Promise.all成功啦');   
        })
        .catch(err=>{
          console.log(err,'Promise.all错啦');
        })

p1,p2,p3都是返回promise实例,Promise.all不关心他们的执行顺序,如果他们都返回成功的状态,Promise.all则返回成功的状态,输出一个数组,是这三个p1,p2,p3的返回值,数组的顺序和他们的执行顺序无关,和他们作为参数排列的顺序有关 我们看下输出

为了是拉长接口三的返回时间我对接口三的数据进行了修改,返回值是长度1000-2000之间的随机数组,所以p3的执行要晚于p1和p2, 但我们输出的arr,p3依然在前面,这给我们带来一个便利,返回值数组的顺序和方法的执行顺序无关,可以进行人为进行控制 我们将p1做一下改动,使p1报错

代码语言:javascript
复制
 const p1 = axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise1')
        .then(({
          data
        }) => {
          console.log('p1成功啦');
          return xxxx.data//将data.data修改为xxxx.data
        })

如果有一个返回失败(reject),Promise.all则返回失败(reject)的状态,此时第一个被reject的实例的返回值,会传递给P的回调函数。 三个promise实例参数之间是“与”的关系,全部成功,Promise.all就返回成功,有一个失败,Promise.all就返回失败 换个角度说,一个promise的执行结果依赖于另外几个promise的执行结果, 例如: 几个ajax全部执行完了,才能渲染页面, 几个ajax全部执行完了,才能做一些数据的计算操作, 不关心执行顺序,只关心集体的执行结果

Promise.race()

Promise中的竞态,用法和Promise.all类似,对应参数的要求和Promise.all相同,传入一个数组作为参数,参数要返回一个Promise实例 race就是竞争的意思,数组内的Promise实例,谁执行的快,就返回谁的执行结果,不管是成功还是失败

代码语言:javascript
复制
const p = Promise.race([p3, p1, p2])
        .then(res => {
          console.log(res);
          console.log('Promise.all成功啦');   
        })
        .catch(err=>{
          console.log(err,'Promise.all错啦');
        })

通过输出我们发现 p1是第一个完成的,所以p的返回结果就是p1的执行结果 而且就算完成,但是 进程不会立即停止,还会继续执行下去。

关于race的使用场景

搜了一下,很多文章都说是用来解决网络超时的提示,类似于下面这样

代码语言:javascript
复制
      const p3 = axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/mock')
        .then(({
          data
        }) => {
          console.log('p3成功啦');
          return data.data
        })
      const p4 = new Promise(function (resolve, reject) {
        setTimeout(() => reject(new Error('网络连接超时')), 50)
      })
     const p = Promise.race([p3, p4])
        .then(res => console.log(res))
        .catch(err => console.log(err));

p3的ajax和50ms的定时器比较,看谁执行的快,如果超过了50ms,p3的ajax还没返回,就告知用户网络连接超时 这里有个问题,就算提示超时了,p3还在继续执行,它并没有停下来,直到有状态返回 个人观点:race可以用来为ajax请求的时长划定范围,如果ajax请求时长超过xxxms会执行某个方法,或者ajax请求时长不超过xxms会执行某个方法,总之,race的应用空间不是很大

Promise.finally()

finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。

代码语言:javascript
复制
      const p = Promise.race([p3, p4])
        .then(res => console.log(res))
        .catch(err => console.log(err))
        .finally(() => {
          console.log("finally的执行与状态无关")
        });

当promise得到状态(不论成功或失败)后就会执行finally,

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 准备工作
  • Promise.all()
  • Promise.race()
    • 关于race的使用场景
    • Promise.finally()
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档