小程序 ES6 Promise用法讲解

 

一:什么是promise

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。Promise对象是一个代理对象,一个代表未知返回结果的对象值。这个值在Promise对象创建时可能是未知的,它允许你为异步操作的成功和失败分别绑定相应的处理方法, 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是返回一个能代表未来出现的结果的promise对象,看起来很抽象,还是用实例来了解吧!

二:状态

pending:初始状态

fulfilled:成功状态

rejected:失败状态

1、fulfilled、rejected被统称为settled,fulfilled也可被称为resolved即为正确时走的状态

2、只有两种状态变化过程:pending → fulfilled,pending → rejected,且状态只可变化一次,一旦发生变化便会一直保持这个结果。

三、使用

new Promise(executor)

executor:一个带有两个参数(resolve和reject)的方法,resolve为fulfilled状态,即成功之后调用,reject为rejected状态,即失败之后调用。

即:new Promise(function(resolve, reject){})

1、executor在创建Promise对象时立即调用

2、若executor函数中抛出错误,promise状态为rejected,executor函数返回值被忽略

先 new一个Promise,示例如下:

    let p = new Promise(function (resolve, reject) {
      //做一些异步操作
      setTimeout(function () {
        console.log('执行完成Promise');
        resolve('要返回的数据可以任何数据例如接口返回数据');
      }, 2000);
    });

刷新页面会发现过了2秒控制台直接打出:

执行完成Promise

其执行过程是:执行了一个异步操作,也就是setTimeout,2秒后,输出“执行完成”,并且调用resolve方法。在随后介绍的then方法中,可获取resolve方法所传回的值。

注意!我只是new了一个对象,并没有调用它,我们传进去的函数就已经执行了,可放在方法中需要的时候进行调用如下所示:

  onclickPromise:function(){
    console.log('放在方法中被调用')
    let p = new Promise(function (resolve, reject) {
      //做一些异步操作
      setTimeout(function () {
        console.log('执行完成Promise');
        resolve('要返回的数据可以任何数据例如接口返回数据');
      }, 2000);
    });
    return p;
  }

调用为:

this.onclickPromise();

 

四:方法

1、Promise.then(resolve[, reject])

resolve为成功回调函数,reject为失败回调函数(可选),参数为Promise实例返回值

 promiseClick: function (num){
    let p = new Promise(function (resolve, reject) {
      setTimeout(function () {
        console.log('数值:', num)
        if (num <= 10) {
          resolve(num);
        }
        else {
          reject('数字大于10了即将执行失败回调');
        }
      }, 2000);
    })
		   return p
  }

调用then的例子如下:

this.promiseClick(4).then(
      function (data) {
        console.log('resolved成功回调');
        console.log('成功回调接受的值:', data);
      },
      function (reason, data) {
        console.log('rejected失败回调');
        console.log('失败执行回调抛出失败原因:', reason);
        console.log('失败执行回调data是什么:', data);
      }
    );

当传入的值为4时,执行正确操作,调用resolve方法:

数值: 4
resolved成功回调
成功回调接受的值: 4

输入11时执行错误接口调用reject方法,输出如下:

数值: 11
rejected失败回调
失败执行回调抛出失败原因: 数字大于10了即将执行失败回调
失败执行回调data是什么: undefined

从上面的结果可知,在then方法中,放在第一位的方法表示正确时处理的方法,放在第二位的方法表示错误是调用的方法。

reject: (reason?: any)方法的参数可以是any,这样在then就是传什么输出什么。resolve: (value?: any)也一样,都是回填在then方法中的第一个参数。

 

promise().then().then().then() 

then支持延续任务调用方式,下面所示在第一个promiseClick1(1).then中调用promiseClick2,进入第二个then然后再调用promiseClick3

  var that = this
    this.promiseClick1(1).then(
      function(data) {
        console.log('resolved成功回调');
        that.promiseClick2(3)
      }).then(
        function (data) {
          that.promiseClick3(3)
      })

 

2、Promise.catch(reject)

处理内容包括:① rejected状态对应返回结果,② catch方法前抛出的错误

  this.promiseClick(11).then(
        function(data) {
          console.log('resolved成功回调');
          console.log('成功回调接受的值:', data);
        })
      .catch(function(reason, data) {
        console.log('catch到rejected失败回调');
        console.log('catch失败执行回调抛出失败原因:', reason);
      });

错误的时候执行结果走catch:

数值: 11
catch到rejected失败回调
catch失败执行回调抛出失败原因: 数字大于10了即将执行失败回调

效果和写在then的第二个参数里面一样。它将大于10的情况下的失败回调的原因输出,但是,它还有另外一个作用:在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中。如下:

   this.promiseClick(4).then(
        function(data) {
          console.log('resolved成功回调');
          console.log('成功回调接受的值:', data);
          console.log(noData);

        })
      .catch(function(reason, data) {
        console.log('catch到rejected失败回调');
        console.log('catch失败执行回调抛出失败原因:', reason);
      });

在第一个then中调用console.log(noData);方法,由于noData未定义,所以会马上执行cath方法中,输出如下

数值: 4
resolved成功回调
成功回调接受的值: 4
catch到rejected失败回调
catch失败执行回调抛出失败原因: ReferenceError: noData is not defined
  

3、Promise.all([p1, p2, ... , p(n)])

p(n)(n = 1, 2, ... )均为Promise实例

***注:返回Promise实例的状态为rejected,即Promise实例的状态为rejected,且没有catch方法做异常处理
 

   Promise.all([this.promiseClick3(4), this.promiseClick2(12), this.promiseClick1(11)])
      .then(function(results) {
        console.log(results);

      })
      .catch(function (reason, data) {
        console.log('catch到rejected失败回调');
        console.log('catch失败执行回调抛出失败原因:', reason);
      });
  },

  promiseClick1: function(num) {
    let p = new Promise(function(resolve, reject) {
      setTimeout(function() {
        console.log('数值:', num)
        if (num <= 10) {
          resolve(num);
        } else {
          reject("promiseClick1数字大于10了即将执行失败回调");
        }
      }, 2000);
    })
    return p
  },

  promiseClick2: function(num) {
    let p = new Promise(function(resolve, reject) {
      setTimeout(function() {
        console.log('数值:', num)
        if (num <= 10) {
          resolve(num);
        } else {
          reject("promiseClick2数字大于10了即将执行失败回调");
        }
      }, 2000);
    })
    return p
  },

  promiseClick3: function(num) {
    let p = new Promise(function(resolve, reject) {
      setTimeout(function() {
        console.log('数值:', num)
        if (num <= 10) {
          resolve(num);
        } else {
          reject("promiseClick3数字大于10了即将执行失败回调");
        }
      }, 2000);
    })
    return p
  }

① 只有参数中所有Promise实例的状态都为fulfilled,该方法返回的Promise实例状态为fulfiiled,意思为所有的都是执行resolve方法,最终才会执行正确的结果,只要有一个是reject方法,最终都是错误的方法,同样会到then里的第二个function或者是catch中。

  Promise.all([this.promiseClick3(4), this.promiseClick2(5), this.promiseClick1(6)])
      .then(function(results) {
        console.log(results);

      });

输出:

数值: 4
数值: 5
数值: 6
[4, 5, 6]

② 参数中返回Promise实例的状态为rejected的数量大于等于1,该方法返回的Promise实例状态为rejected,返回数据为第一个状态变为rejected的参数方法返回结果

   Promise.all([this.promiseClick3(4), this.promiseClick2(12), this.promiseClick1(11)])
      .then(function(results) {
        console.log(results);

      })
      .catch(function (reason, data) {
        console.log('catch到rejected失败回调');
        console.log('catch失败执行回调抛出失败原因:', reason);
      });

输出:

数值: 4
数值: 12
catch到rejected失败回调
catch失败执行回调抛出失败原因: promiseClick2数字大于10了即将执行失败回调
数值: 11

4、Promise.race([p1, p2, ... , p(n)])

p(n)(n = 1, 2, ... )均为Promise实例

all是等所有的异步操作都执行完了再执行then方法,那么race方法就是相反的,谁先执行完成就先执行回调。

    Promise
      .race([this.promiseClick3(5), this.promiseClick2(11), this.promiseClick1(12)])
      .then(function (results) {
        console.log("第一个function:"+results);
      }, function (reason) {
        console.log("第二个function:" +reason);
      });

输出:

数值: 5
第一个function:5
数值: 11
数值: 12

调用:

    Promise
      .race([this.promiseClick3(11), this.promiseClick2(5), this.promiseClick1(12)])
      .then(function (results) {
        console.log("第一个function:"+results);
      }, function (reason) {
        console.log("第二个function:" +reason);
      });

输出:

数值: 11
第二个function:promiseClick3数字大于10了即将执行失败回调
数值: 5
数值: 12

从以上例子可以看出,只会进入一个then的方法,而且是根据第一个执行的状态进行判断。

5:Promise.finally( )

   finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作

  this.promiseClick1(1).then(
      function(data) {
        console.log('resolved成功回调');
        console.log('成功回调接受的值:', nodata);
      }).catch(
      function(data) {
        console.log('catch:' + data);
      }).finally(
      function(data) {
        console.log('不管过程是咋样的,最终都会走到finally方法中');
      })

结果:

数值: 1
resolved成功回调
catch:ReferenceError: nodata is not defined
不管过程是咋样的,最终都会走到finally方法中

6:promise.done( )

Promise 对象的回调链,不管以then方法或catch方法结尾,要是最后一个方法抛出错误,都有可能无法捕捉到(因为 Promise 内部的错误不会冒泡到全局)。因此,我们可以提供一个done方法,总是处于回调链的尾端,保证抛出任何可能出现的错误。

 

 

 

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值