zoukankan      html  css  js  c++  java
  • 14-Promise

    1、Promise

    Promise 是 ES6 中一个非常重要和好用的特性,是异步编程的一种解决方案;


    通常在网络请求时,我们会处理异步事件,因为不能立即拿到结果,所以往往会传入另外一个函数,在数据请求成功时,将数据通过传入的函数回调出去;


    如果只是一个简单的网络请求,那么这种方案不会给我们带来很大的麻烦,但当网络请求非常复杂时,就会出现回调地狱;


    2、网络请求的回调地狱

    我们来考虑下面的场景:

    • 通过一个 url1 从服务器加载一个数据 data1,data1 中包含了下一个请求的 url2
    • 再通过 data1 取出 url2,从服务器加载数据 data2,data2 中包含了下一个请求的 url3
    • 再通过 data2 取出 url3,从服务器加载数据 data3,data3 中包含了下一个请求的 url4
    • 最后发送网络请求 url4,获取最终的数据 data4


    图片.png


    正常情况下,上面的代码不会有什么问题,可以正常运行,并且获取我们想要的结果;


    但是,这样的代码难看而且不容易维护;


    我们期望的是以一种更加优雅的方式来进行这种异步操作:使用 Promise


    3、定时器的异步事件

    用一个定时器来模拟异步事件:

    图片.png


    假设下面的 data 是从网络上 1 秒后请求的数据,console.log 就是我们的处理方式,


    这是过去的处理方式,我们将它换成 Promise 代码:

    图片.png


    这个例子会让我们感觉使用 Promise 有些多此一举,因为下面的 Promise 代码明显比上面的代码看起来还要复杂;


    定时器异步事件解析

    我们先来认认真真的读一读这个程序到底做了什么?

    • new Promise 创建了一个 Promise 对象
    • 小括号中 ((resolve, reject) => {}) 是一个箭头函数
      • 在创建 Promise 时,传入的这个箭头函数是固定的(一般我们都会这样写)
      • resolve 和 reject 也是函数,通常情况下,会根据请求数据的成功和失败来决定调用哪一个
        • 如果是成功的,通常会调用 resolve(messsage),这时,后续的 then 会被回调
        • 如果是失败的,通常会调用 reject(error),这时,后续的 catch 会被回调


    4、promise 的三种状态

    当开发中有异步操作时,可以给异步操作包装一个 Promise,异步操作之后会有三种状态:

    • pending:等待状态,比如正在进行网络请求,或者定时器没有到时间
    • fulfill:满足状态,当我们主动回调了 resolve 时,就处于该状态,并且会回调 .then()
    • reject:拒绝状态,当我们主动回调了 reject 时,就处于该状态,并且会回调 .catch()

    图片.png


    以上代码的另一种写法:

    图片.png


    5、Primose的链式调用

    <script>
      // promise 链式调用
      new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('Hello World')
        }, 1000)
      }).then(data => {
        console.log(data) // Hello World
        return Promise.resolve(data + '111')
      }).then(data => {
        console.log(data) // Hello World111
        return Promise.resolve(data + '222')
      }).then(data => {
        console.log(data) // Hello World111222
        return Promise.reject(data + 'error')
      }).then(data => {
        console.log(data) // 这里代码不会执行,没有输出
        return Promise.resolve(data + '333')
      }).catch(data => {
        console.log(data) // Hello World111222error
        return Promise.resolve(data + '444')
      }).then(data => {
        console.log(data) // Hello World111222error444
      })
    </script>


    链式调用简写

    将数据直接包装成 Promise.resolve,在 then 中直接返回:

    <script>
      // promise 链式调用简写
     new Promise((resolve, reject) => {
      setTimeout(() => {
            resolve('Hello World')
          }, 1000)
      }).then(data => {
        console.log(data) // Hello World
        return data + '111'
      }).then(data => {
        console.log(data) // Hello World111
        return data + '222'
      }).then(data => {
        console.log(data) // Hello World111222
        return Promise.reject(data + 'error')
      }).then(data => {
        console.log(data) // 这里代码不会执行,没有输出
        return data + '333'
      }).catch(data => {
        console.log(data) // Hello World111222error
        return data + '444'
      }).then(data => {
        console.log(data) // Hello World111222error444
      })
    </script>


    6、promise的all方法的使用

    <script>
      // Promise 的 all 方法使用
      Promise.all([
        new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve({
              name: 'lyy',
              age: 18
            })
          }, 1000)
        }),
        new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve({
              name: 'sss',
              age: 17
            })
          }, 2000)
        })
      ]).then(results => {
        console.log(results);
      })
    </script>


  • 相关阅读:
    GIT → 04:Git与代码托管平台
    GIT → 03:Git的下载和安装
    GIT → 02:Git和Svn比较
    GIT → 01:学习版本控制的原因
    GIT → 00:GIT学习大纲
    GIT → 10:基于IntelliJ IDEA的Git 操作
    GIT → 11:Git 工作流与实战演练
    GIT → 09:TortoiseGit 图形化工具
    亚马逊服务器搭建pptp方法
    Safari获取UDID需要安装.mobileconfig文件,
  • 原文地址:https://www.cnblogs.com/weiyiming007/p/13729908.html
Copyright © 2011-2022 走看看