Promise

作者: Do_Du | 来源:发表于2020-02-21 20:17 被阅读0次

    Promise是异步变成的一种解决方案,比传统的解决方案--回调函数和时间 更合理和更强大。
    Promise就是为了解决回调函数嵌套的一种解决方案。

    Promise有三种状态,分别是pending(进行中),resolved(已成功),rejected(已失败),一旦达到相应的状态,就会回调相应的方法。其实称作已成功,或者已失败并不准确,ES6中标准说法fullfiled,rejected。至于什么是已成功状态,什么是已失败状态,可以自己按照实际情况自定义。

    一、为什么要用Promise

    串行的加载10页数据(每页9张海报),即第一页加载完成后,启动第二页的加载,以此类推

    $(document).ready(function(){
          //获取第一页数据
          $.getJSON("json/poster.json?page=1",function(result){
           attachPoster(result);
           //获取第二页数据
           $.getJSON("json/poster.json?page=2",function(result){
              attachPoster(result);
              //获取第三页数据
              $.getJSON("json/poster.json?page=3",function(result){
                attachPoster(result);
                 ...
              });
          });
         });
        });  
    

    为了解决这种无限回调,就有了Promise

    二、Promise是什么

    上面的例子改成下面的

    function getPoster(page){
          const promise = new Promise(function(resolve,reject){
            $.getJSON("json/poster.json?page="+page,function(result){
              resolve(result);
            })
          });
          return promise;
        }
        getPoster(1).then(function(result){//获取第一页
          attachPoster(result); 
          return getPoster(2);
        }).then(function(result){//获取二页
          attachPoster(result); 
          return getPoster(3);
        }).then(funciton(result){//获取第三页 ...})
    

    比第一种的层层嵌套Promise写法更清晰,更符合逻辑

    三、then与resolve

      function getPObj(){ //  (2)
          var p = new Promise(function(resolve,reject){ //  (3)
            setTimeout(function(){    //  (4)
             console.log("开始执行定时器");   //  (5)
             resolve("执行回调方法");  // (6)
           },2000);
          });
          return p;
        }
     getPObj(); // (1)
    

    结果:


    image.png

    将代码改为如下:

     function getPObj(){ //  (2)
          var p = new Promise(function(resolve,reject){ //  (3)
            setTimeout(function(){    //  (4)
             console.log("开始执行定时器");   //  (5)
             resolve("执行回调方法");  // (6) 即执行下面的then 回调方法;参数即为then的data
           },2000);
          });
          return p;
        }
        getPObj().then(function(data){  //  getPObj() => (1)  then(function(data) =>(7)
           console.log("我是回调方法");
           console.log(data);
        });
    
    image.png

    再改代码如下,实现更多链式调用

      function getPObj(num){
          var p = new Promise(function(resolve,reject){
            setTimeout(function(){
             console.log("开始执行定时器:"+num);
             resolve(num);
           },2000);
          });
          return p;
        }
        getPObj(1).then(function(data){
           console.log("我是回调方法");
           console.log("执行回调方法:"+data);
           return getPObj(2);
        }).then(function(data){
           console.log("我是回调方法");
           console.log("执行回调方法:"+data);
           return getPObj(3);
        }).then(function(data){
           console.log("我是回调方法");
           console.log("执行回调方法:"+data);
        });
    
    image.png

    四、reject

    then方法有两个入参,分别实现resolved,rejected的回调方法。
    我们在方法增加控制,生成一个1-10的随机方法,如果大于5就表示失败。

     function getPObj(num){
          var p = new Promise(function(resolve,reject){
            setTimeout(function(){
             console.log("开始执行定时器:"+num);
              var i = Math.ceil(Math.random()*10); //生成1-10的随机数
              if (i<5) {
               resolve(num);
             }else{
              //构造一个error作为入参
              reject(new Error("Error"));
            } 
          },2000);
          });
          return p;
        }
         
        getPObj(1).then(function(data){
          console.log("执行回调方法:"+data);
          return getPObj(2);
         }).then(function(data){
          console.log("执行回调方法:"+data);
           return getPObj(3);
         }).then(function(data){
          console.log("执行回调方法:"+data);
         }).catch(function(e){
            console.log(e);
        });
    
    image.png

    七、all、race

    Promise.all可以将几个Promise对象封装成一个,格式如下:
    当这几个对象都变成resolved状态后,总状态变为resolved;否则,其中有一个为rejected状态,则变成reject,其他的可以忽略。可以理解为p1&&p2&&p3。

    function getPObj(num){
          var p = new Promise(function(resolve,reject){
            setTimeout(function(){
             console.log("开始执行定时器:"+num);
             resolve(num);
          },2000);
          });
          return p;
        }
     
        Promise.all([getPObj(1),getPObj(2),getPObj(3)]).then(function(data){
                console.log("resolve");
                console.log(data);
             }).catch(function(e){
                 console.log("error");
                 console.log(e);
       })
    
    image.png

    2、race

    race与all类似,页可以将几个Promise对象封装成一个,格式如下:

    Promise.race([p1,p2,p3]).then(function(data){...})
    不同的时,看谁执行的快,then就回到回调谁的结果。可以理解为p1||p2||p3

    function getPObj(num){
          var p = new Promise(function(resolve,reject){
            setTimeout(function(){
             console.log("开始执行定时器:"+num);
              var i = Math.ceil(Math.random()*10); //生成1-10的随机数
              if (i<5) {
               resolve(num);
             }else{
              reject(num);
            } 
          },2000);
          });
          return p;
        }
     
        Promise.race([getPObj(1),getPObj(2),getPObj(3)]).then(function(data){
                console.log("resolve");
                console.log(data);
             }).catch(function(e){
                 console.log("error");
                 console.log(e);
             })
    

    当接受到第一个对象的resolved状态后,其他的两个抛弃处理。


    image.png

    转自:https://blog.csdn.net/tcy83/article/details/80274772

    相关文章

      网友评论

          本文标题:Promise

          本文链接:https://www.haomeiwen.com/subject/ebznsctx.html