一、什么是Promise?

Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,通过构造函数可以实例化对象new Promise(),用来封装异步操作并可以获取其成功或失败的结果。

那什么时候我们会来处理异步事件呢?

一种很常见的场景应该就是网络请求了。我们封装一个网络请求的函数,因为不能立即拿到结果,所以不能像简单的3+4=7一样将结果返回。所以往往我们会传入另外一个函数,在数据请求成功时,将数据通过传入的函数回调出去。如果只是一个简单的网络请求,那么这种方案不会给我们带来很大的麻烦。

二、什么情况下会用到Promise?

一般情况下是有异步操作时(io操作如:文件io、数据库io、网络请求),使用Promise对这个异步操作进行封装。让多层嵌套变为链式调用,更为优雅。

三、如何使用Promise?

<script>
  // 1.使用setTimeout
  // setTimeout(() => {
  //   console.log('Hello World');
  // }, 1000)

  // new -> 构造函数(1.保存了一些状态信息  2.执行传入的函数)
  // 在执行传入的回调函数时, 会传入两个参数, resolve, reject本身又是函数
  new Promise((resolve, reject) => {
    setTimeout(() => {
      // 成功的时候调用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);
  })
</script>

四、Promise三种状态

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

4.1 pending:等待状态

比如正在进行网络请求,或者定时器没有到时间。

4.2 fulfill:满足状态

当我们主动回调了resolve时,就处于该状态,并且会回调.then()

4.3 reject:拒绝状态

当我们主动回调了reject时,就处于该状态,并且会回调.catch()

promise的另一种处理形式

<script>
  new Promise((resolve, reject) => {
    setTimeout(() => {
      // resolve('Hello Vuejs')
      reject('error message')
    }, 1000)
  }).then(data => {
    console.log(data);
  }, err => {
    console.log(err);
  })
</script>

五、Promise链式调用

<script>
  // 参数 -> 函数(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 Vuejs');
    return new Promise((resolve, reject) => {
      // 第三次网络请求的代码
      setTimeout(() => {
        resolve()
      })
    })
  }).then(() => {
    // 第三处理的代码
    console.log('Hello Python');
  })
</script>

六、Promise的all方法

Promise.all([
    new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({name: 'why', age: 18})
      }, 2000)
    }),
    new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({name: 'kobe', age: 19})
      }, 1000)
    })
  ]).then(results => {
    console.log(results); //当两个模拟网络请求都完成,才会打印results数组
  })