前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >初识Promise

初识Promise

作者头像
挥刀北上
发布2019-08-06 16:13:05
5330
发布2019-08-06 16:13:05
举报
文章被收录于专栏:Node.js开发

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

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

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

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

代码语言:javascript
复制
new Promise(function(resolve,reject){
  console.log("1")
})

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

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

  • pedding状态,这个状态不是成功也不是失败;
  • fullfiled状态,就是成功状态,想要达到这个状态需要调用resolve方法;
  • rejected状态,想要达到这个状态需要调用reject方法;

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

转换图如下:

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

代码语言:javascript
复制
var p = new Promise(function(resolve,reject){
    console.log("1")
});

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

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

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

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

代码语言:javascript
复制
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里面来,那要怎么实现呢,看代码:

代码语言:javascript
复制
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,幸福生活在一起也不会执行,那这有是没用呢,刚才的判断出轨是同步执行的将其替换为异步执行测试一下,代码如下:

代码语言:javascript
复制
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实现会是什么样呢,看代码:

代码语言:javascript
复制
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还有一些很有意思的用法,不是一篇文章能讲完的,咱们下次继续。

有疑问可给此公众号发送信息。

欢迎转发!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-11-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 nodejs全栈开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档