zoukankan      html  css  js  c++  java
  • 初识Promise

    什么是promise?MDN官方文档的解释如下:

    Promise 对象用于一个异步操作的最终完成(或失败)及其结果值的表示。简单点说,就是处理异步请求,我们经常会做些承诺,如果我赢了我就做A事情,如果输了我就做B事情。

    这就是promise的中文含义:诺言,一个成功,一个失败。

    那Promise在js中到底是个什么东西呢?看以下代码,可在浏览器中将其打印出来,如图:

    通过prototype可以看出promise是一个构造函数。咱们先new一个promise看看能执行什么,代码如下:

    new Promise(function(resolve,reject){
     console.log("1")
    })

    这段代码直接打印出了1,在这段代码中,Promise的参数是一个函数,这个函数有两个参数,resolve,reject,按照官方文档的说法,Promise 对象用于表示一个异步操作的最终完成(或失败)及其结果的值

    什么意思呢?就是promise这个值刚一定义出来,并不知道代码会是完成状态或是失败状态,所以Promise存在了三种状态:

    • pedding状态,这个状态不是成功也不是失败;

    • fullfiled状态,就是成功状态,想要达到这个状态需要调用resolve方法;

    • rejected状态,想要达到这个状态需要调用reject方法;

    其中,状态只能由pedding变换为rejected或者fulldied,不可逆转。

    转换图如下:

    将上面的代码放在浏览器里面,就会直接执行,打印出1,所以我需要将它用一个函数包裹一下:

    var p = new Promise(function(resolve,reject){
       console.log("1")
    });

    这样只需要在使用Promise时,调用这个函数就可以了。有人可能会问这有什么用,我直接实行console.log(1)不就行了,干嘛要包在Promise里面呢,什么鬼?这个需要回到Promise的作用上面来。

    Promise的作用是什么?通俗的讲就是控制异步函数的调用。

    上面的代码还不足以看出Promise的威力,只是告诉大家如何将Promise放到一个函数里面。

    接着咱们按照文章开头举的是否嫁给我的例子来看一段代码:

    function WeddingOrNot(){
       return new Promise(function(resolve, reject){
           setTimeout(function(){
               if(Math.random()-0.5>0){        
                 resolve('你要嫁给我,咱们下一步去领证');
               }else{
                 reject('你不会嫁给我,后面的不需要执行了,咱们到此结束,')
               }
           }, 2000);
       });          
    }
    WeddingOrNot().then(function(data){
     console.log(data);
    }).then(function(){
     console.log("买喜糖")
    }).then(function(){
     console.log("发请柬")
    }).then(function(){
     console.log('幸福的生活在一起')
    }).catch(function(data){
     console.log(data);
     console.log('直接执行catch,所有的then都不会执行')
    })

    weddingornot是否结婚,是一个异步函数。是否结婚存在一个概率问题,这里用Math.random来计算:

      • 如果嫁给我,将结果传递给resolve,将Promise由pedding状态变换为fullfiled状态,后面紧跟的then方法中的function会得到传递出过来的数据,并且then链调用会同步一个一个逐步执行;

      • 如果不结婚,将结果传递给reject,后面的then一个都不会执行,直接跳到catch里面来执行。

    分别看下执行结果如图:

    或者

    有兴趣的朋友可以自己测试一下。

    假如结婚后中间出了一些状况离婚了,也需要直接跳到catch里面来,那要怎么实现呢,看代码:

    function WeddingOrNot(){
       return new Promise(function(resolve, reject){
           setTimeout(function(){
               if(Math.random()-0.5>0){        
                 resolve('你要嫁给我,咱们下一步去领证');
               }else{
                 reject('你不会嫁给我,后面的不需要执行了,咱们到此结束,')
               }
           }, 2000);
       });          
    }
    WeddingOrNot().then(function(data){
     console.log(data);
    }).then(function(){
     console.log("买喜糖")
    }).then(function(){
     console.log("发请柬")
    }).then(function(){
     return new Promise(function(resolve,reject){
       
       if(Math.random()-0.5>0){
                 console.log("经历了诱惑,没有出轨,继续在一起")      
                 resolve('经历了诱惑,没有出轨,继续在一起');
               }else{
                 reject("有人出轨,婚姻到此结束了,直接执行catch")
               }

     })
    }).then(function(){
     console.log('幸福的生活在一起')
    }).catch(function(data){
     console.log(data);
     console.log('直接执行catch,所有的then都不会执行')
    })

    读代码,在发请柬幸福的生活在一起之间咱们插入了一个then,里面的函数呢返回了一个Promise实例,并且这个实例会变为rejected或者fullfiled状态,并将结果传递出去。看下运行结果:

    或者

    可以看出,在then链的调用中,某个then返回另外一个promise实例,且也是按照随机数来变换promise的状态的。如果调动了reject,幸福生活在一起也不会执行,那这有是没用呢,刚才的判断出轨是同步执行的将其替换为异步执行测试一下,代码如下:

    function WeddingOrNot(){
       return new Promise(function(resolve, reject){
           setTimeout(function(){
               if(Math.random()-0.5>0){        
                 resolve('你要嫁给我,咱们下一步去领证');
               }else{
                 reject('你不会嫁给我,后面的不需要执行了,咱们到此结束,')
               }
           }, 2000);
       });          
    }
    WeddingOrNot().then(function(data){
     console.log(data);
    }).then(function(){
     console.log("买喜糖")
    }).then(function(){
     console.log("发请柬")
    }).then(function(){
     return new Promise(function(resolve,reject){
       setTimeout(function(){
         if(Math.random()-0.3>0){
           console.log('经历了诱惑,没有出轨,继续在一起')        
                 resolve('经历了诱惑,没有出轨,继续在一起');

               }else{
                 reject("有人出轨,婚姻到此结束了,直接执行catch")
               }
       },1000)
     })
    }).then(function(){
     console.log('幸福的生活在一起')
    }).catch(function(data){
     console.log(data);
     console.log('直接执行catch,所有的then都不会执行')
    })

    来看执行结果:

    或者

    或者

    代码照样会按照你设计的then链逐步调用——这就是promise的威力。

    关于结婚不结婚这个案例,如果不用promise实现会是什么样呢,看代码:

    function xingfu(){
     console.log("幸福的生活在一起")
    }
    function lihun(){
     console.log("离婚了")
    }
    setTimeout(function(){
     if (Math.random()-0.5>0) {
       console.log("结婚继续往下走");
       console.log("买喜糖")
       console.log("发请柬");
       setTimeout(function(){
         if (Math.random()-0.3>0) {
           console.log("经历了诱惑继续在一起")
           xingfu();
         } else {
           console.log('有人出轨了,结束了')
           lihun()
         }
       },300)
     } else {
       lihun()
     }
    },300)

    运行结果大家自己去测试,这里就不贴图了。

    可以看到,这段代码的组织结构产生了回调嵌套,组织代码顺序完全不如用promise实现看着顺眼。当然有的朋友会说:一个两个嵌套而已,还好。

    那如果嵌套三个,四个,五个......想象一下。

    promise还有一些很有意思的用法,不是一篇文章能讲完的,咱们下次继续。

    坚持下去就能成功
  • 相关阅读:
    python 面向对象类成员(字段 方法 属性)
    python 面向对象三大特性(封装 多态 继承)
    python 正则
    python 反射机制 ( 广泛应用于URL参数)
    python 导入模块
    python 字符串格式化 ( 百分号 & format )
    python time
    python filter
    【工作感悟】——揭开“PM”的面纱
    【SSH】——spring的控制反转和依赖注入
  • 原文地址:https://www.cnblogs.com/suoking/p/8984741.html
Copyright © 2011-2022 走看看