P14.3-Promise终极链式调用写法

举报
brucexiaogui 发表于 2021/11/25 23:17:09 2021/11/25
【摘要】 P14.3-Promise终极链式调用写法 文章目录 P14.3-Promise终极链式调用写法1.概述2.Promise链式调用思想3.Promise链式调用标准写法4.Promise链式调用...

P14.3-Promise终极链式调用写法

1.概述

使用Promise封装多层异步调用时,调用层级越多,重复代码就越多,这个时候我们可将重复的代码去掉,简化封装异步请求的代码。这种简化写法就是Promise链式调用

2.Promise链式调用思想

我们在看Promise的流程图时,发现无论是then还是catch都可以返回一个Promise对象。
所以,我们的代码其实是可以进行链式调用的:

  • 这里我们直接通过Promise包装了一下新的数据,将Promise对象返回了
  • Promise.resovle():将数据包装成Promise对象,并且在内部回调resolve()函数
  • Promise.reject():将数据包装成Promise对象,并且在内部回调reject()函数

3.Promise链式调用标准写法

这种链式写法是一个标准的写法,每次请求都会创建一个Promise对象在对象中发送下次异步请求。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>


<script>


  // 参数 -> 函数(resolve, reject)
  // resolve, reject本身它们又是函数
  // 链式编程
  new Promise((resolve, reject) => {

    // 第一次网络请求的代码
    setTimeout(() => {
      resolve()
    }, 1000)

  }).then(() => {
    // 第一次拿到结果的处理代码
    console.log('Hello World');
    console.log('Hello World');
    console.log('Hello World');
    console.log('Hello World');
    console.log('Hello World');
    console.log('Hello World');

    return new Promise((resolve, reject) => {

      // 第二次网络请求的代码
      setTimeout(() => {
        resolve()
      }, 1000)
    })
  }).then(() => {

    // 第二次处理的代码
    console.log('Hello Vuejs');
    console.log('Hello Vuejs');
    console.log('Hello Vuejs');
    console.log('Hello Vuejs');
    console.log('Hello Vuejs');
    console.log('Hello Vuejs');

    return new Promise((resolve, reject) => {

      // 第三次网络请求的代码
      setTimeout(() => {
        resolve()
      })
    })
  }).then(() => {

    // 第三处理的代码
    console.log('Hello Python');
    console.log('Hello Python');
    console.log('Hello Python');
    console.log('Hello Python');
    console.log('Hello Python');
  })
</script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

4.Promise链式调用第一种简化写法

需求场景描述
第一次异步请求返回结果,在第一请求中进行处理。然后将处理结果传递给第二次请求
第二次请求拿到第一次异步请求处理的结果进行处理后发送第二次请求
第三次请求拿到第二次请求处理的结果进行处理然后发送第三次请求
注意在这个场景中只有第一次是异步请求,后面不是异步请求。只是拿到上次结果做处理然后发送请求。

4.1.Promise链式调用标准写法

首先使用标准链式调用方法实现上面的场景需求。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<script>
 
  /* 需求描述
  网络请求: aaa -> 自己处理(10行)
  处理: aaa111 -> 自己处理(10行)
  处理: aaa111222 -> 自己处理 */
  
  new Promise((resolve, reject) => {
  //只有第一次请求使用了setTime异步请求
    setTimeout(() => {
      resolve('aaa')
    }, 1000)
  }).then(res => {
    // 1.自己处理10行代码
    console.log(res, '第一层的10行处理代码');
  
    // 2.对结果进行第一次处理
    return new Promise((resolve, reject) => {
      // resolve(res + '111')
      reject('err')
    })
  }).then(res => {
    console.log(res, '第二层的10行处理代码');
  
    return new Promise(resolve => {
      resolve(res + '222')
    })
  }).then(res => {
    console.log(res, '第三层的10行处理代码');
  }).catch(err => {
    console.log(err);
  })
</script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

4.2.Promise链式调用第一次简化写法

上面的代码只有第一次使用了异步请求,后面的请求都是调用上次resolve函数返回的结果,所以我们可以去掉后面创建Promise对象。每次都返回Promise对象调用resolve返回的结果,如果是调用reject,同理只需将resolve替换成reject即可。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<script>
 // new Promise(resolve => resolve(结果))简写
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('aaa')
    }, 1000)
  }).then(res => {
    // 1.自己处理10行代码
    console.log(res, '第一层的10行处理代码');

    // 2.对结果进行第一次处理
    return Promise.resolve(res + '111')
  }).then(res => {
    console.log(res, '第二层的10行处理代码');

    return Promise.resolve(res + '222')
  }).then(res => {
    console.log(res, '第三层的10行处理代码');
  })
</script>
</body>
</html> 

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

4.3.Promise链式调用第终极简化写法

上面代码中每次处理请求返回的结果(return Promise.resolve(res + ‘111’))都要手动通过Promise.resolve调用resole函数 ,这个也是重复的代码,我们也可以省去,代码内部会自动进行包装处理。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<script>
// 省略掉Promise.resolve
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('aaa')
    }, 1000)
  }).then(res => {
    // 1.自己处理10行代码
    console.log(res, '第一层的10行处理代码');

    // 2.对结果进行第一次处理
    return res + '111'
  }).then(res => {
    console.log(res, '第二层的10行处理代码');

    return res + '222'
  }).then(res => {
    console.log(res, '第三层的10行处理代码');
  })
</script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

4.4.Promise链式调用包含请求失败写法

上面所有的链式调用都是建立在假设所有请求都是成功情况下的写法,在真实请求中会出现请求失败情况,这里我们就加上请求失败来写链式调用。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<script>
new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('aaa')
    }, 1000)
  }).then(res => {
    // 1.自己处理10行代码
    console.log(res, '第一层的10行处理代码');

    // 2.对结果进行第一次处理,执行到这里假如请求失败了调用reject函数。后面的请求都不在执行直接调用最后一行的catch函数处理请求失败代码。
    return Promise.reject('error message')
  }).then(res => {
    console.log(res, '第二层的10行处理代码');

    return Promise.resolve(res + '222')
  }).then(res => {
    console.log(res, '第三层的10行处理代码');
  }).catch(err => {
    console.log(err);
  })
</script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

在这里插入图片描述

文章来源: brucelong.blog.csdn.net,作者:Bruce小鬼,版权归原作者所有,如需转载,请联系作者。

原文链接:brucelong.blog.csdn.net/article/details/111997668

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。