Promise对象详解

      Promise是异步编程的一种解决办法,比起传统的解决方案——回调函数和事件——更合理且更强大。有了Promise对象,就可以将异步操作以同步操作的流程表达出来。

    Promise对象的特点:

        1、对象的状态不受外界影响。三种状态分别是:Pending(进行中)/Fulfilled(已成功)/Rejected(已失败)。

        2、一旦状态改变就不会再变。状态改变只有两种可能:Pending—>Fulfilled、Pending—>Rejected。

注意:博文后面的Resolved统一指Fulfilled状态,不包含Rejected。

1.基本用法

创建一个Promise实例:Promise对象是一个构造函数,用来生成Promise实例,其中resolve和reject由JavaScript引擎提供

 
var promise = new Promise(function(resolve, reject){
     //...some code
    if(/*异步操作成功*/){
        resolve(value);//状态从Pending——>Fulfilled时调用
    }else{
        reject(error);//状态从Pending——>Rejected时调用
    }
});

Promise实例生成后,可以用then方法分别指出Resolved状态和Rejected状态的回调函数。

promise.then(function(value){
    //success
},function(error){
    //failure
});

then方法接受两个回调函数作为参数:第一个回调函数是Promise对象的状态变为Resolved时调用,第二个回调函数是Promise对象的状态变为Rejected时调用。其中第二个参数可选。Promise实例的状态定型后,就会触发then绑定的回调函数。

另外注意:Promise新建后会立即执行,但then方法指定的回调函数将在当前脚本所有同步任务执行完后才会执行。例:

let promise = new Promise(function(resolve, reject){
    console.log("Promise");
    resolve();
});
promise.then(function () {
    console.log("Resolved.");
});
console.log("Hi!");
打印出来的信息为:
Promise
Hi!
Resolved.

2.Promise中的一些方法

 

  • Promise.prototype.then():使用方式跟前面基本用法中介绍的一样,但是得注意,then方法返回的是一个新的Promise实例(不是原来那个),因此可以采用链式写法,即then方法后面可以再调用另一个then或catch。这个是Promise中最重要也最主要的用法,实现异步操作同步化就使用这个方法。
  • Promise.prototype.catch():是.then(null, rejection)的别名,用于指定发生错误时的回调函数。返回的还是一个Promise对象,故后面可以再调用then或catch方法。Promise对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。但捕获是单向的,只能是后面的捕获前面的。例:
getJSON('/post/1.json').then(function (post) {
    return getJSON(post.commentURL);
}).then(function (comments) {
    //some code
}).catch(function (error) {
    //处理前面3个Promise产生的错误
});

    另外,推荐使用:promise.then(function(data){//success}).catch(function(err){//error});

              不推荐使用:promise.then(function(data){//success},function(err){//error});

               理由是方法一可以捕获到then方法执行的错误。

 

  • Promise.all():用于将多个Promise实例封装成一个新的Promise实例。例:var p = Promise.all([p1, p2, p3]):只有数组中的实例均为Fulfilled时,p才为Fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数;要有一个为Rejected,p的状态就为Rejected,此时第一个被Rejected的实例的返回值会传递给p的回调函数。

另外:如果作为参数(数组中元素)的Promise实例自身定义了catch方法,那么它被rejected时并不会触发Promise.all()的catch方法。  例如:如果p1触发了它自身的catch,该实例执行完catch方法也会变成resolved,导致Promise.all()方法参数里面的三个实例都会resolved,因此会调用p的then方法指定的回掉函数,而不会调用catch方法指定的回调函数。

需要特别注意的是,Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚。这带来了一个绝大的好处:在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题。

  • Promise.race():也是将多个Promise实例包装成一个新的Promise实例。但两者略有不同,例:var p = Promise.race([p1,p2,p3]);只要p1、p2、p3中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的Promise实例的返回值就传递给p的回调函数。
  • Promise.resolve():将现有对象转为Promise对象。例:var jsPromise = Promise.resolve(参数);参数分为四种:

Promise对象:原封不动的返回这个实例;

thenable对象(具有then方法的对象):将这个对象转为Promise对象,然后立即执行thenable对象的then方法;

不具有then方法的对象或根本不是对象:返回一个状态为Resolved的新Promise对象;

不带有任何参数:会在本轮“事件循环”结束时创建,会直接返回一个Resolved状态的Promise对象。

 

  • Promise.reject():返回一个新的Promise实例,状态为Rejected。例:var p = Promise.reject(参数);注意:参数会原封不动的作为rejected的理由变成后续方法的参数,即参数是对象,后续方法捕获到的就是对象。
  • Promise.try():让同步函数或异步函数都可使用Promise来处理。例:Promise.try(fucntion(){}).then(...).catch(...);目前还只是一个提案

两个附加的方法:

  • done():总是处于回调链的尾端,保证捕获到任何可能出现的错误,并向全局抛出。只捕获错误。
  • finally():用于指定不管Promise对象最后状态如何都会执行的操作。它与done方法的最大区别在于,它接受一个普通的回调函数作为参数,该函数不管怎样都必须执行。例:.finally(callback);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值