JS新手——十分好玩的promise初级

来源:互联网 发布:mac怎么制作铃声 编辑:程序博客网 时间:2024/05/16 07:43

ES6标准出了之后,各路大神反复提的一个新亮点,叫promise。我刚开始看了之后,并不是特别懂。最近玩了玩nodejs,对异步的概念有了一个初步的了解之后,才算有点明白这种机制的设计。再次和各位新手朋友分享一下我对于promise的理解。
提示:这里只为了初学的朋友,有一定了解的同学就不要浪费时间阅读了啊!

1:为什么要用promise

1.1 异步回调

大道理我不太会说,我尽量通俗一点。在js语言中,我们将会使用大量的异步回调函数。这位会问,什么叫异步回调函数?举个例子,大家肯定都会:

        window.setTimeout(function(){            console.log('我在2秒后执行!');        },2000);        console.log('我会马上执行!');

上面的代码就是一个最简单的异步调用的例子,简单说,setTimeout因为具有异步机制,里面的回调函数并不会阻塞下面代码的执行,保证了代码的执行效率。这个回调函数就是异步回调函数。

1.2 异步回调的一个小问题

上面的例子我们看完之后,我们在开发中可能接着会遇到一个问题,比如,因为某项需求,我们需要在2秒后在用一个1秒的定时器,那我们可以这么写吗?
(这个例子举的极不恰当,因为时间的先后实际上是一个同步的概念,并不适合拿到异步来讨论,只不过定时器比较好些,大家可以理解为一个异步需要等待另外一个异步的结果即可。)

        window.setTimeout(function(){            console.log('我在2秒后执行!');        },2000);        window.setTimeout(function(){            console.log('我想在上面的2秒之后再1秒后执行!');        },1000);        console.log('我会马上执行!');

这个大家又都会明白,肯定是不会按顺序执行的,执行的结果必然是:
这里写图片描述
所以为了保证我们想要的效果,我们必须是保证在第一个定时器的回调函数里面再引用第二个定时器。代码如下:

        window.setTimeout(function(){            console.log('我在2秒后执行!');            window.setTimeout(function(){            console.log('我想在上面的2秒之后再1秒后执行!');            },1000);        },2000);        console.log('我会马上执行!');

这样执行就没毛病了。可是!这种嵌套两层还好,多了的话又看的乱,又不好维护,所以给开发人员带来了很大麻烦。这就是promise设计的由来。

2:什么是promise

从我粗浅的理解来看,以上面两个定时器为例。promise就是一个保证定时器1执行后,再执行定时器2的机制。那么我又有一个问题要思考了:这与同步有什么区别呢?这个问题我后面讲(也可能要更新讲,目前是想的不太清楚)。

2:怎么用promise

下面我们来看promise是如何用的。
Promise是js的一个对象,这个新手不用太纠结,大可以理解为像Array,Math,Date这样的内置对象一样,只是js自带的一种构造函数。它的格式是这样的:

new Promise(function(resolve,reject){...})

function(resolve,reject)里面放的即是我们要使用的第一个异步回调函数,拿上面的例子将就是定时器1。resolve代表的是成功执行这个异步回调函数的状态,rejecet表示的是未成功执行的状态。
话不多说,例子最直观,我们先来尝尝鲜:

        var p1= new Promise(function(resolve,reject){          resolve('success');        });        p1.then(function(val){          console.log('返回值是'+val);//输出结果为:‘返回值是success’        });

还可以在then里面接着返回值,给下一步的then用

         var p1= new Promise(function(resolve,reject){          resolve('success');         });         var p2=p1.then(function(val){                      return 'success2'         });         p2.then(function(val){           console.log('返回值是'+val);         });//输出结果为:“返回值是success2”

then里面也可以返回Promise对象,这样下次then调用的参数就是新promise里面的resolve的值:

         var p1= new Promise(function(resolve,reject){          resolve('success');         });         var p2=p1.then(function(val){                      return new Promise(function(resolve,reject){              resolve('success3');           })         });         p2.then(function(val){           console.log('返回值是'+val);         });//输出内容:‘返回值是success3’

then里面可以调用两个函数,一个为成功后的执行函数,另外一个为失败后的执行函数;

         var p1= new Promise(function(resolve,reject){          resolve('success');         });         var p2=p1.then(function(val){                      return new Promise(function(resolve,reject){              reject('fail');           });         });         p2.then(function(val){           console.log('返回值是'+val);         },function(reason){          console.log('失败原因是'+reason);         });//返回:失败原因是fail

3 一个例子

下面的例子实现的功能是一个抽奖,大家可以去试一下,体会一下promise的感觉。

      var rate = [0.8,0.5,0.3];      var award = 0;      var request = function(round){        return new Promise(function(resolve,reject){          var rand = Math.random();          if(rand<rate[round]){            console.log(rand);            resolve((round+1));          }else{            console.log('很遗憾,第'+(round+1)+'关没有过');            console.log('奖金总额'+award);            reject();          }        });      }      request(0).then(function(val){        award += val;        return request(1);      }).then(function(val){        award += val;        return request(2);      }).then(function(val){        award += val;        console.log('奖金总额'+award);      });
0 0
原创粉丝点击