ES6之Promise

ES6中为原生JS新增加了一个对象用来解决异步编程和问题,这个对象就是Promise。

那promise究竟是什么呢?这个真的是一件很难解释清楚的事情,他一共有三种状态,就像是一个岔路口,不管你来或者不来,我都在这里,这时候的状态是初始状态,也就是pending(进行时)。当你走到分岔口的时候,只能向左(fulfilled:成功)或者向右(rejected:失败),而且没有回头的权利(promise的状态不可以改变)。当然,你也可能一辈子走不到那个岔路口。这里只是一个比喻。

我们先来看一下语法

var num;
var promise = new Promise(function(resolve,reject){
if (num){
resolve(num);
   }else{
reject();
   }
});

首先,new了一个Promise对象,传了一个函数,里面传了两个参数,第一个参数代表成功,第二个参数代表失败。

我在最上面定义了一个变量num,如果num的值为真的,就会选择resolve,如果失败了,就会选择reject。

但上面这些代码还不够,这些代码只是决定了promise的状态,并没有执行呢,我们先来复习一遍。

想要创建一个Promise对象,需要先new一下,然后传一个函数,函数的两个参数分别代表了promise的两种状态,如果特定的条件成立,promise的状态就会变成成功,否则状态就会变成失败。

现在,我们已经可以成功判断出了小p的状态,可是有了这些还不够,选择了哪条路之后要做的事情是什么呢?继续向前走啊!这时候,我么就要引入一个新的方法来帮助小p继续向前走了,这个方法就是then

then方法里面有两个参数,分别是小p上面两个参数的回调函数,如果小p的状态是成功,就会走then方法的第一个参数,如果小p的状态是失败,就会走tnen方法的第二个回调函数。只这样给大家说可能不是很好理解,我们再来看一个例子:

var num=1;
var promise = new Promise(function(resolve,reject){
if (num){
resolve(num);
   }else{
reject();
   }
});
promise.then(()=>console.log('成功'),()=>{console.log('失败')});

我们给then方法传了两个函数,如果小p的状态是成功,就会执行第一个函数,打印出成功,反之亦然。

我们先来判断一下小p的状态,如果num是真的,小p选择的路就是成功,如果num是假的,小p选择的路就是失败。

num的值为1,是真的,证明这时候小p选择的是成功的那条路,然后之后调用了then方法继续向前走,如果状态是成功就会执行第一个函数,反之亦然,那么打印出来的应该是成功,我们打开浏览器看一下猜想是否正确。

成功

浏览器打印出来了,证明我们刚刚的猜想没有错误。

现在我们已经能够正确的判断出小p的状态并且让他执行了,可是有的人觉得then里面传两个函数的写法太low了,把成功状态和失败状态的方法写在一起容易混淆,有没有逼格更高的一点写法?

当然有了。这个方法的名字是catch,专门用来放错误状态下执行的函数。先来看一下基本语法:

promise
.then(()=>console.log('成功'))
.catch(()=>{console.log('失败')});

呐~,这就是你们想要的逼格高的写法,其实和上面的没什么两样,只不过现在then里面只传了一个函数,就是成功状态下要执行的函数,那么失败状态下呢?就会直接执行catch里面的代码了。

还是回到最初的例子,我们的小p现在已经选择了一条路向前走了,人生的路途中难免有错误的决定,小p也是一样的,可是最难过的是我们做出错误的决定的时候,我们自己往往是不知晓的,这时候我们就需要一个明智的人来为我们指点一二,告诉我们什么是对,什么是错,让我们的人生少走弯路。小p人生,不对,码生的这位智者就是catch,在小p犯错误的时候及时制止,避免继续错误的走下去。

我们来看一下具体的代码

var num=1;

var promise = new

Promise(function(resolve,reject){

    if (num){

       console.log(a);

        resolve(num);

    }else{

        reject();

    }

});

promise.then(()=>console.log('成功')).catch(()=>console.log('失败'));

我们看上面的代码,虽然特定的条件成立,但仍然会走catch函数,提醒小p发生了错误,避免继续错下去。

如果我们人生也有一位这样的智者,应该会避免很多错误,可惜没有如果。

再来介绍几个方法,promise也算是入门了。

今天要介绍的第一个方法名字是finally(),基本语法和then和catch一样,我们来看一下:

let num=1;

let promise = new Promise((resolve,reject)=>{

if(num){

resolve();

}else{

reject();

}

});

promise.then(()=>console.log('成功')).catch(()=>console.log('失败')).finally(()=>console.log('我是最后执行的函数'))

我们先来分析一下,首先定义了一个num的值为1,又写了一个promise,之后如果promise的状态是成功,就会打印出 成功 ,如果状态是失败,就会打印出 失败。但我们定义的num值为1,所以此时promise的状态就是成功的,应该可以打印出 成功 ,但我在最后面又写了一个finaly的方法,里面的函数执行之后会打印出 我是最后执行的函数  。最后一个方法什么时候会执行,暂时还不知道,我们先打开浏览器看一下吧。

浏览器打印出了 成功 和 我是最后执行的函数

我们把num的值改为0再试一次

浏览器打印出了 失败 和 我是最后执行的函数

所以 finally函数不管小p的状态是成功或者失败,都会触发,就像你生命中该遇见的人,不管你有多优秀,或者多狼狈,他都在你做出决定之后,遇见你。

finally函数在小p的状态发生改变之后会执行的操作,不管状态是成功还是失败,都会执行此函数,就像你生命中躲不掉的那个人,遇到了就珍惜吧。



接下来,我们要介绍一个神奇的方法了,这个方法会颠覆你我对传统promise的认知,让你认识到,原来promise还可以这样玩,同时也是一个非常方便的方法。

平时我们写promise的时候一般会先new一下,就像这样

let promise = new Promise((resolve,reject)=>{

if(num){

    resolve();

}else{

    reject();

}

});

但现在有一种更加简单的方法了

let p1 = Peomise.resolve('');

我们打印一下p1看一下


打印出了一个promise实例,而且状态直接是成功,值为传进来的参数

什么 小p居然可以这样操作,对呀,我也是刚刚知道,小p居然可以这样玩。

这个方法可以直接把里面的参数转为promise实例,而且状态为成功。

就像是你辛辛苦苦的学习刷证书努力工作过上你想要的生活,有的人一出生就含着金钥匙出生,过着你努力了那么久的生活,人生本就是如此。

但是 说不定也有例外呢?

我们再来看几个例子

let promise = new Promise(res=>console.log('ddd'));

let p1 = Promise.resolve();

console.log('p1----',p1);

let p2 = Promise.resolve('ddd');

console.log('p2----',p2);

let p3 = Promise.resolve(promise);

console.log('p3----',p3);

我们看看不同的参数对这个神奇的方法有没有影响

打印结果如下


p1里面什么参数都没有传,打印出来的结果是一个成功状态的小p,

p2里面传了一个字符串,打印出来的结果也是一个成功状态下的小p,

p3里面传了一个我自己new的一个小p,结果打印出了一个初始状态下的小p。

我们来总结一下,如果Promise.resolve()里面的参数是一个不是promise实例,那么Promise.resolve就会返回一个成功状态下的promise实例,如果Promise.reslove传了一个promise实例,那么传入的是什么状态,返回的就是什么状态。



与Promise.resolve相反的一个方法叫做Promise.reject()方法,转入什么值打印出来的都是一个错误状态下的回调函数,但与Promise.resolve不同的是这个方法不管传入什么参数都会是失败状态下的promise实例,而且会立即抛出错误

我们来看几个例子

let promise = new Promise(res=>console.log('ddd'));

let p1 = Promise.reject('出错了');

console.log('p1----',p1);

let p2 = Promise.reject();

console.log('p2----',p2);

let p3 = Promise.reject(promise);

console.log('p3----',p3);


如果里面传的参数是字符串,就会返回一个失败状态下的promise实例,而且抛出错误,错误就是传的那个字符串

如果里面没有传递参数,就会返回一个失败状态相爱的promise实例,而且抛出的错误是一个undefined

如果里面传递的是一个promise实例,里面也是返回一个失败状态下的promise实例,抛出的错误是整个promise实例。

这真的是两个神奇的方法,直接让世间万物华丽的逆袭转身,具体是悲是喜,看造物者何用了。



如果一段代码里面有好多个promise实例,那么这样一个一个的调用是否有点麻烦,所以ES6为我们提供了两个可以同时控制多个promis实例的方法。

第一个方法如下

let pAll = Promise.all(['s','e','0']);

这个方法的参数是一个集合,里面的参数都是promise实例,如果不是promise实例的话,里面会自己调用Promise.resolve()方法转为promise实例,这个方法具体的作用是什么呢?

我们先来打印一下看看


里面的三个参数状态都是成功,所以这个大的promise实例的状态也是成功

那如果是别的情况呢?

let p = new Promise(resolve=>console.log('p'));

let pAll = Promise.all(['s','e','0',p]);

console.log(pAll);


只要有一个参数的状态是初始化,整个大的promise实例的状态就会成为初始化

如果有一个promise的状态是失败又会怎样呢?我们来看一下

var n = Promise.reject('失败了');

let pAll = Promise.all(['s','e','0',n]);

console.log(pAll);

浏览器运行的结果如下


只要集合中有一个的状态是失败,那么整个promise的状态就会成为失败,

总结来说,在Promise.all()这个方法参数的集合中,只有全部都是成功,状态才是成功,只要有一个状态是失败,那么整个promise的状态就是失败,如果有一个是初始化,那么状态就是初始化。当然,Promise.all的作用不止于此,今天只是给大家简单的介绍了一下,如果有兴趣的话可以后台私信我获取更加详细的笔记。

与Promise.all相对的方法有一个,就是Promise.race,同样是用来控制promise集合的一个大的promise实例,如果集合里面的参数不是promise实例,也会调用Promise.reslove来转为成功的promise实例。

他们的区别是Promise.race集合中只要有一个promise的实例发生改变,整个大的promise实例的状态就会跟着改变,最先改变的那个promise实例的返回值,就会传给大的promise实例

我们来看一个具体的例子

let pAll = Promise.race(['s','e','0']);

console.log(pAll);

传的三个参数都不是promise实例,所以会先调用Promise.resolve方法,都会转为成功的promise实例,所以大的promise状态就是成功

如果第一个参数的状态是失败会是什么呢?

var n = Promise.reject('失败了');

let pAll = Promise.race([n,'s','e','0']);

console.log(pAll);


如果第一个状态为失败,大的promise的状态就会变成失败,如果集合内的promise都是初始状态呢?

var n = new Promise(res=>console.log('c'));

var f = new Promise(res=>console.log('c'));

var c = new Promise(res=>console.log('c'));

let pAll = Promise.race([n,f,c]);

console.log(pAll);


如果三个状态是初始状态测不会有任何改变,只要有一个promise的状态发生了改变,大的promise的状态就会立刻改变

关于promise的知识点目前就说这么多吧,如果后台私信想了解更多的话会考虑后期更新的


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值