ES6 Promise简析

  • Promise是做什么的
    Promise是异步编程的一种解决方案。
  • 什么时候我们会来处理异步事件
    在开发时,比较常见的是在网络请求的时候处理异步操作。我们封装一个网络请求的函数,因为不能立即拿到结果,所以不能像简单的3+4=7一样将结果返回。所以往往我们会传入另外一个函数,在数据请求成功时,将数据通过传入的函数回调出去。如果只是一个简单的网络请求,那么这种方案不会给我们带来很大麻烦。但是当网络请求很复杂时,就会出现回调地狱
  • 考虑以下场景(夸张成分)
    1.我们需要通过一个url1从服务器加载一个数据data1,data1中包含了下一个请求的url2
    2.我们需要通过data1取出url2,从服务器加载数据data2,data2中包含了下一个请求的url3
    3.我们需要通过data2取出url3,从服务器加载数据data3,data3中包含了下一个请求的url4
    4.发送网络请求url4,最终获取数据data4
    $ajax('url1',function(data1){
      $ajax(data1['url2'],function(data2){
        $ajax(data2['url3'],function(data3){
          $ajax(data3['url4'],function(data4){
            console.log(data4);
          })
        })
      })
    })

这样看来代码结构还是很清晰的,但是一般来说当我们拿到data1时不会立即去获取url2,data1要先处理业务,此时如果data1的业务代码有100行,然后才获取url2,再次发送网络请求,此时就会发现data1和第二层网络请求之间有100行代码,结构就会比较乱,此时如果其他data也需要处理业务,代码就会变得难以维护,难以管理。
那么如何才能用良好的方式处理这种异步操作呢?那就是使用Promise。

Promise基本语法

  1. 我们用一个定时器来模拟异步事件:
    -假设下面的data时从网络上1s后请求的数据
    -console.log就是我们的处理方式
    //1.使用setTimeout
    setTimeout(()=>{
      console.log('hello,world');
      setTimeout(() => {
        console.log('hello Vue');
        setTimeout(() => {
          console.log('hello ES6');
        },1000)
      },1000)
    },1000)
    //参数 -> 函数(resolve,reject)
    //resolve,reject本身又是函数
    //链式编程
    new Promise((resolve, reject) => {
      //第一次网络请求的代码
      setTimeout(() => {
        resolve();
      }, 1000)
    }).then(() => {
      // 第一次拿到结果的处理代码
      console.log('hello,world');

      return new Promise((resolve, reject) => {
        //第二次网络请求的代码
        setTimeout(() => {
          resolve();
        }, 1000)
      })
    }).then(() => {
      // 第二次拿到结果的处理代码
      console.log('hello Vue');

      return new Promise((resolve, reject) => {
        //第三次网络请求的代码
        setTimeout(() => {
          resolve();
        }, 1000)
      })
    }).then(() => {
      // 第三次拿到结果的处理代码
      console.log('hello ES6');
    })

// 什么情况下会用到Promise
// 一般情况下是有异步操作时,使用Promise对异步操作进行封装
// new -> 构造函数(1.保存了一些状态信息 2.执行传入的函数)
// 在执行传入的回调函数时,会传入俩个参数,resolve,reject本身又是函数

    new Promise((resolve, reject) => {
      setTimeout((data) => {
        //成功的时候调用resolve
        resolve('hello world');

        // 失败的时候调用reject
        reject('error message')
      }, 1000)
    }).then((data) => {
      //1.100行的处理代码 
      console.log(data);
      console.log(data);
      console.log(data);
    }).catch((err) => {
      console.log(err);
    })
   //Promise的另一种写法
    new Promise((resolve, reject) => {
      setTimeout(() => {
        // resolve('hello world');
        reject('error message')
      }, 1000)
    }).then((data) => {
      console.log(data);
    }, (err) => {
      console.log(err);
    })

Promise的链式调用例子

 // wrapped into
    //网络请求:aaa -> 自己先处理(10行)然后拼接一个111
    //处理:aaa111 -> 自己处理(10行) 然后拼接一个111
    //处理aaa111222  ->   自己处理
    new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('aaa');
      }, 1000)
    }).then((res) => {
      // 自己处理十行代码
      console.log(res);
      console.log(res, '第一层的十行处理代码');

      // 2.对我们的结果进行第一次处理
      //return new Promise((resolve) => {
     //   resolve(res + '111')

     // })
      //这里也可以写成
      return Promise.resolve(res + '111')
      //也可以
      //return res+'111'
    }).then((res) => {
      console.log(res);
      console.log(res, '第二层的十行处理代码');

      // 3.对结果进行第二次处理
      return new Promise((resolve) => {
        resolve(res + '222');
      })
    }).then((res) => {
      console.log(res);
      console.log(res, '第三层的十行处理代码');
    })

输出

aaa
aaa 第一层的十行处理代码
aaa111
aaa111 第二层的十行处理代码
aaa111222
04-Promise的链式调用(二).html:41 aaa111222 第三层的十行处理代码

Promise all

当我们现在有一种需求,即两种网络网络状态都满足进行下一步操作,这个时候就需要Promise all

    Promise.all([
      // new Promise((resolve, reject) => {
      //   $ajax({
      //     url: 'url1',
      //     success: function (data) {
      //       resolve(data);
      //     }
      //   })
      // }),
      // new Promise((resolve, reject) => {
      //   $ajax({
      //     url: 'url2',
      //     success: function (data) {
      //       resolve(data);
      //     }
      //   })
      // })

      new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('result1')
        }, 2000)
      }),
      new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('result2')
        }, 1000)
      })
    ]).then(results => {
      console.log(results);
    })

输出

(2) ["result1", "result2"]
0: "result1"
1: "result2"
length: 2
[[Prototype]]: Array(0)

Promise三种状态

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值