浅谈ES6中Promise

promise是ES6中新增的一个用于处理异步请求的一个对象。

Promise

上面的图片展示了promise的基本 的方法和状态。

那么如何使用 promise呢?

1. 创建一个 Promise实例

    const promise = new Promise((resolve, reject) => {
      if (/* fulfilled */){
        return resolve(value)  
      } else {  // rejected
        return reject(error)
      }
    })
const promise = new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('执行完成promise')
        return resolve('abcdef')
      }, 2000)
    })

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由JavaScript引擎提供,不用自己部署。其中resolve是异步操作成功时回调,reject为异步操作失败时回调。(一般来说,在调用了resolvereject后,Promise的使命就完成了,后继操作应放在then方法里面,而不是直接写在resolve或reject后面。所以最好在resolve或reject前面加入return

 

2.使用 Promise.prototype.then()

then方法可以接受两个回调函数作为参数。第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数。

    promise.then((value) => {
      // resolved
    }, (error) => {
      // rejected
    })
//then中的 data 就是 promise 中resolve()的值
promise.then((data) => {    //
        console.log(data)
      })

回调函数1:

      Promise对象的状态变为resolved时调用。

回调函数2(可选):

      Promise对象的状态变为rejected时调用。一般不写在 then方法里面,promise有专门处理失败的方法 Promise.prototype.catch()

3.Promise.prototype.catch()

Promise.prototype.catch方法是.then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

    promise.then((value) => {
      // resolved
    }).catch((error) => {
        // 1.rejected
        // 2.then内部发生错误
    })

Promise对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。一般来说,不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。

4.Promise.prototype.finally()

finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于Promise的执行结果。所以就是只要用了这个 promise,就会调用 finally这个方法

    promise.then(result => {
        // resolved
    }).catch(error => {
        // 1.rejected
        // 2.then内部发生错误
    }).finally(() => {
        // 与状态无关
    })
promise
      .then((data) => {
        console.log(data)
      })
      .finally(() => {
        console.log('finally')
      })

 打印出,说明finally里面的会执行

finally方法总是会返回原来的值。

    Promise.prototype.finally = function (callback) {
      let P = this.constructor
      return this.then(
        // 不管前面的 Promise 是fulfilled还是rejected,都会执行回调函数callback
        value  => P.resolve(callback()).then(() => value),
        reason => P.resolve(callback()).then(() => { throw reason })
      )
    }

5.Promise.all([p1,p2])

参数:

  • p1、p2都是Promise实例;
  • 如果不是Promise实例,则会先调用Promise.resolve()将其转为Promise实例;
  • 可以不是数组,但必须具备Interator接口.

返回值:

  1. 只有p1、p2的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2的返回值组成一个数组,传递给p的回调函数。
function promiseClick1() {
      let p = new Promise(function (resolve, reject) {
        setTimeout(function () {
          var num = Math.ceil(Math.random() * 20) //生成1-20的随机数
          console.log('1随机数生成的值:', num)
          if (num <= 10) {
            resolve(num)
          } else {
            reject('1数字大于10了即将执行失败回调')
          }
        }, 1000)
      })
      return p
    }
    function promiseClick2() {
      let p = new Promise(function (resolve, reject) {
        setTimeout(function () {
          var num = Math.ceil(Math.random() * 20) //生成1-20的随机数
          console.log('2随机数生成的值:', num)
          if (num <= 10) {
            resolve(num)
          } else {
            reject('2数字大于10了即将执行失败回调')
          }
        }, 1000)
      })
      return p
    }
    function promiseClick3() {
      let p = new Promise(function (resolve, reject) {
        setTimeout(function () {
          var num = Math.ceil(Math.random() * 20) //生成1-20的随机数
          console.log('3随机数生成的值:', num)
          if (num <= 10) {
            resolve(num)
          } else {
            reject('3数字大于10了即将执行失败回调')
          }
        }, 1001)
      })
      return p
    }

    Promise.all([promiseClick3(), promiseClick2(), promiseClick1()]).then(
      (results) => {
        console.log(results)
      }
    ).catch((reason,data) => {
      console.log('reason',reason)
      console.log('data',data)
    })

打印出来的结果如下:

 全部成功返回(resolve):

有部分没有成功返回(reject):

2.只要p1、p2之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

3.如果作为参数的Promise实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()catch方法。

    const p1 = new Promise((resolve) => {
        setTimeout(() => {
            console.log('p1')
            return resolve('p1 resolved')
        }, 3000)
    })
    
    const p2 = new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('p2')
            return reject('p2 rejected')
        }, 1000)
    }).catch((error) => {
        console.log(error)
    })
    
    Promise.all([p1, p2]).then((result) => {
        console.log(result)
    }).catch((error) => {
        console.log(error)
    })

6.Promise.race([p1, p2])

参数:

  • Promise.all(p1, p2)

如果数组中有多个Promise对象, 谁先返回状态就听谁的, 后返回的会被抛弃

如果数组中不是Promise对象, 那么会直接执行then方法

返回值:

  1. 只要p1、p2之中有一个实例率先改变状态,p的状态就跟着改变。
        // p2提前被rejected
        
        const p1 = new Promise((resolve) => {
            setTimeout(() => {
                console.log('p1')
                return resolve('p1 resolved')
            }, 3000)
        })
        
        const p2 = new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log('p2')
                return reject('p2 rejected')
            }, 1000)
        })
        
        Promise.race([p1, p2]).then((result) => {
            console.log(result)
        })
        .catch((error) => {
            console.log(error)
        })
    

    // p1提前被resolved
    
    const p1 = new Promise((resolve) => {
        setTimeout(() => {
            console.log('p1')
            return resolve('p1 resolved')
        }, 1000)
    })
    
    const p2 = new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('p2')
            return reject('p2 rejected')
        }, 3000)
    })
    
    Promise.race([p1, p2]).then((result) => {
        console.log(result)
    })
    .catch((error) => {
        console.log(error)
    })

 

Promise.race([p1, p2])只执行参数里面的一个,不论是resolve出来的结果还是reject出来的结果,执行了一个以后就不执行其他的。

 

本文章参考主要借鉴于:https://juejin.cn/post/6844904032385892359

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值