• Promise对象


     javascript中实现异步编程的四种方式。分别是1.回调函数 2.事件监听 3.发布、订阅事件 4.promise对象 

    Promises对象是在CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口。现已在ECMAScript2015(ES6)中实现。

    Promise 对象用于延迟(deferred) 计算和异步(asynchronous ) 计算.。一个Promise对象代表着一个还未完成,但预期将来会完成的操作。

    Promise 对象是一个返回值的代理,这个返回值在promise对象创建时未必已知。它允许你为异步操作的成功或失败指定处理方法。 这使得异步方法可以像同步方法那样返回值:异步方法会返回一个包含了原返回值的 promise 对象来替代原返回值。 

    Promise对象有以下几种状态:

    pending: 表示一个初始状态, 非 fulfilled 或 rejected。

    fulfilled: 成功的操作。

    rejected: 失败的操作。

    每一个异步任务都会返回一个Promise对象,该对象有一个then方法,允许指定回调函数。可以根据Promise对象的状态相应的去执行对应的回调函数。

    二、常用的API

    1.Promise.prototype.then()

    promise实例具有then方法,因此then方法是定义在原型对象promise.prototype上的。它的作用是为promise实例添加状态改变时的回调函数。

    then()方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。then方法返回的是一个新的promise实例,非原来的那个promise实例,因此可以采用链式写法,then方法之后还可调用一个then方法。

    var p=new Promise(function(resolve,reject){
        resolve("ok");    
    });
    p.then(function(value){console.log(val)},
     function(err)(console.log(err))       
    );

    then方法的第二个参数一般不推荐写。有以下两个原因:第一个原因,由于是链式操作,这个then方法之后还可能会有其他操作,如果此时把错误捕捉的函数放在后面方法前边的话,并且之后再无错误捕获方法,then之后的错误就会捕捉不到。第二个原因是在then方法里面,两个参数都是回调函数写了一大堆,这样结构看起来比较混乱。

    所以下面就有了这个方法,一般写在链式写法的最后。这样就可以捕获到前面所有的错误。

    2.Promise.prototype.catch()

    这个方法是.then(null,rejection)的别名,这也能看出这个方法是专门只能用来捕获错误信息,用于指定发生错误时的回调函数。

    但是使用这个这个方法的时候要注意一下几点:

    (1)当promise状态已经变成resolved的时候,再抛出错误时是无效的。看下面的代码。

    var promise=new promise(function(resolve,reject){
       resolve("ok");
       throw new Error("test");      
    });
    promise.then(function(value){consloe.log(val); })
                .catch(function(error){console.log(err)});

    promise状态在resolve("ok");之后就会把promise的状态变为resolved,之后抛出错误也不会把promise状态变为rejected,所以catch方法并不会捕获到错误。

    Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况有任意一种发生,状态就相当于凝固了,不会再变了,会一直保持这个结果。

     (2)尽量将catch方法写在链式操作的最后,原因上面都已经说过了,也正是捕获错误不推荐写then方法的原因之一。错误会一直冒泡到最后,catch放在最后会捕捉到所有错误。当catch设置的过早,并且之后在没有catch方法的话,那么这个catch之后发生的错误不会被捕获到。

    (3)当没有使用catch方法指定错误处理函数的回调函数时,promise对象里面抛出的错误不会传递到外层的代码。

    3.Promise.resolve()

    这个方法的作用就是将现有的对象转化为Promise对象,进而可以执行这些方法。

    Promise.resolve("foo");
    
    //这就相当于下面这种写法
    
    new Promise(function(resolve){
       resolve("foo");     
    });

    4.Promise.all()

    这个方法用于将多个promise实例,包装成一个新的promise实例。

    var p=Promise.all([p1,p2,p3]);

    p1,p2,p3都是promise对象的实例,如果不是的话,则会调用Promise.resolve()方法,将参数转化为Promise实例,之后再继续进行进一步的处理。

    并且要注意一下两点:

    (1)只有当p1,p2,p3状态都变为fulfilled之后,p的状态才会变为fulfilled。

    (2)只要p1.p2,p3中有任意一个状态变为rejected,p的状态就会变为rejected。

    三、实现异步编程的原理

    大概原理就是正如它们所说Promise对象相当于是一个状态机,在其内部使用resolve方法,使其由初始状态变为成功时的fulfilled状态或者执行失败后的rejected状态。这时内部的工作就完成了,开始由外部监听其内部的状态的改变,调用then()方法(catch()方法相当于then内部的第二个参数方法)对应的状态调用对应的处理函数。这样就大概是Promise对象实现异步编程的原理。

  • 相关阅读:
    人物-IT-张志东:张志东
    人物-IT-任正非:任正非
    人物-IT-张朝阳:张朝阳
    院校-清华大学:清华大学
    人物-丁磊:丁磊
    人物-李彦宏:李彦宏
    人物-IT-马云:马云
    inittab
    initlocation
    initdb
  • 原文地址:https://www.cnblogs.com/xumqfaith/p/7808664.html
Copyright © 2020-2023  润新知