初识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还有一些很有意思的用法,不是一篇文章能讲完的,咱们下次继续。

posted @ 2018-05-03 12:27  挥刀  阅读(303)  评论(0编辑  收藏  举报