zoukankan      html  css  js  c++  java
  • ES6 - promise对象

    Promise的设计初衷

    我们使用ajax请求数据,得到数据后再对数据进行操作,可是有时候,对得到的数据进行操作的过程中,可能又要用到ajax请求,这时,我们的代码就变成了这样:

    $.ajax({

      success:function(res1){

        //...请求B开始,B依赖A返回的数据

        $.ajax({

          sucess:function(res2){

            //...请求C开始,C依赖B返回的数据

            $.ajax({

              sucess:function(res3){

              }

            });

          }

        });

      }

    });

    这种写法的不足:

    (1)当多个请求层层依赖的话,就会很多层嵌套,代码的可读性会变得很差,也不利于调试,当一个逻辑层修改的时候可能会引起多个层的变化。

    (2)如果C依赖于A和B的结果,但A,B彼此独立,按照上边的写法,B也要等A执行完之后才可以执行,消耗了更多的等待时间。

    为了避免这种回调函数层层嵌套(回调地狱)的形式,ES6 给出了Promise。

    • Promise对象能使我们更加合理、更加规范的进行异步操作。

    下面我们来正式介绍Promise。

    (1)Promise的基本用法:

    let pro=new Promise(function(resolve,reject){

    });

    Promise对象是一个全局对象,创建Promise实例的时候,参数是一个匿名函数,其中有两个参数:resolve,reject。

    这两个参数均为方法,resolve方法处理一步操作成功后的业务,reject方法处理业务操作失败后的业务。

    (2)Promise的三种状态

    • pending:刚刚创建一个Promise实例的时候,表示初始状态。
    • fulfilled:resolve方法调用的时候,表示操作成功。
    • rejected:reject方法调用的时候,表示操作失败

    状态的转化只能是:初始态(pending)->成功(fulfilled),或者,初始态(pending) ->失败(rejected) (不能逆向转换,也无法在成功与失败之间转换)

    let pro=new Promise(function(resolve,reject){

      //实例化后的状态:pending

      if(成功){

        resolve();    //状态:fulfiled

      }else{

        reject();    //状态 : rejected

      }

    });

    (3)then()方法

    用于绑定处理操作后的处理程序。

    pro.then(function(res){

      //操作成功的处理程序

      },function(error){

      //操作失败的处理程序

    })

    (3)catch()方法

    对于操作异常的程序,使用catch()方法。

    pro.catch(function(error){

      //操作失败的处理程序

    });

    当操作层层依赖的时候,Promise的处理方法:

    看一个完整的案例:

    let pro=new Promise(function(resolve,reject){

      if(true){

        resolve();

      }else{

        reject();

      }

    });

    //用then处理操作成功,用catch处理操作异常

     pro.then(requestA)

      .then(requestB)

      .then(requestC)

      .catch(requestError);

    function requestA(){

      console.log('Aok');

      return 'next B';

    }

    function requestB(res){

      console.log('Aresult:'+res);

      console.log('Bok')

      return 'next C';

    }

    function requestC(res){

      console.log('Bresult:'+res);

      console.log('Cok')

    }

    function requestError(){

      console.log('false');

    }

     

    //结果:

    Aok

    Aresult:next B

    Bok

    Bresult:next C

    Cok

    可以看出,使用then方法,三个请求不必在层层嵌套。当B依赖A时,我们使用return将A的结果返回,B使用参数接受这个结果

    几个重要的方法:

    (1)Promise.all()

    接受一个数组作为参数,数组的元素是Promise实力对象,当参数中对象的状态全部返回fulfilled的时候,Promise才会返回。

    let pro1=new Promise(function(resolve){

      setTimeout(function(){

        resolve('eg1_ok');

      },5000);

    });

    let pro2=new Promise(function(resolve){

      setTimeout(function(){

        resolve('eg2_ok');

      },2000);

    });

    Promise.all([pro1,pro2]).then(function(result){

      console.log(result);   //['eg1_ok','eg2_ok']

    }) //在等待pro1,pro2都进入fulfilled状态(5000ms)后,promise.all() 才执行。

    当我们执行的某个操作需要多个接口返回的数据来支持,而这多个接口又是互不依赖的,这时候我们就可以用Promise.all(),它会在所有的接口都请求成功后才操作。

    (2)Promise.race()方法

    与Promise.all()的区别在于,所有的参数实例中,只要又一个状态变化(无论成功还是失败),就会执行,其他实例中再发生变化,它也不管了。

     

    let pro1=new Promise(function(resolve){

      setTimeout(function(){

        resolve('eg1_ok');

      },5000);

    });

    let pro2=new Promise(function(resolve){

      setTimeout(function(){

        reject('eg2_false');

      },2000);

    });

     

    Promise.race([pro1,pro2]).then(function(result){

      console.log(result);   

    }).catch(function(error){

      console.log(error)

    });

     //eg2_false 

     

     

    _______________

    参考:公众号 web前端教程 

     

  • 相关阅读:
    使用v-if刷新生命周期
    vue element 上传图片 文件
    vue中既能获取事件对象又能获取参数的方法
    element-ui跨行
    云原生体系下 Serverless 弹性探索与实践
    PaddlePaddle:在 Serverless 架构上十几行代码实现 OCR 能力
    谷粒商城笔记-环境配置(2)——文件上传、java参数验证、递归,分页、事务
    java 前端技术选型(Vue.js+Element.ui)
    java实现woff字体解析,逆向反爬
    自定义dom重现函数useResume
  • 原文地址:https://www.cnblogs.com/telnetzhang/p/5786000.html
Copyright © 2011-2022 走看看