零、回顾
上节课我们实现了登录代码的封装,并最终将登录代码模块化放在了一个文件里,
这节课我们开始学习Promise,并基于Promise改造我们代码。
Promise表示一个异步操作对象,它让我们可以在外部处理异步操作完成或者失败的时候的结果。
Promise是ED6的一个标准内置对象,是为了解决Javasript开发中,一贯存在的回调地狱问题而推出的。
微信小程序目前已经支持了包括Symbol、Set、Map、Promise在内的大部分内置对象以及相关的ES6方法。
在小程序中已经原生支持Promise,不需要在引入第三方的类库。
接下来我们先看一个Promise示例。
一、示例
function func1(){
return new Promise((resolve, reject) => {
setTimeout(() => {
reject('error')
}, 200);
})
}
let promise1 = func1()
promise1.then((res) => {
console.log(res)
},(err)=>{
console.log(err)
});
输出:
error
在这个示例中,我们可以看到,函数func1,它返回了一个异步操作对象Promise,
在这个函数中我们通过定时器模拟了一个异步操作,有一个setTimeout是200ms,
然后我们进行一个reject这样一个error的返回。
它的初始化参数是一个匿名函数,resolve与reject这两个形参,
是可以让我们在消费代码中去定义和传递的,
就是这一块,return new Promise,然后返回Promise对象它的参数,
这个参数我们可以看一下,它其实是一个匿名函数,
这个匿名函数它包括两个形参,第一个是resolve,第二个是reject,
这两个它是在我们消费这个函数的时候,然后去传入进来的,怎么去处理。
这两个形参是让我们在消费代码中去定义和传递的,
其中resolve,它代表异步操作成功了,
在func1中调用这个回调函数,处理调用成功的逻辑,参数是成功对象。
reject代表异步操作失败了,
在func1中调用这个回调函数,处理调用失败的逻辑,参数是失败对象。
一般情况下,它这个参数都是一个error对象,
基于Promise的这种编程方式,它让工具类diamante与开发者的这种消费代码各司其职,
工具类代码只负责处理自己负责的那一块逻辑,而关于成功、失败这种情况下如何处理,
这让开发者在消费代码里面进行处理。
这样代码的分离更加的合理,同时也在一定程度上规避了一些一贯存在的回调函数陷阱,
下面我们重点看一下Promise有哪些方法,以及如何使用它。
二、Promise的方法
Promise对象主要有六个方法,值得我们注意,这就是经常会用到的六个Promise的方法。
Promise.prototype.then()
Promise.prototype.catch()
Promise.prototype.finally()
Promise.all()
Promise.any()
Promise.race()
Promise.allSettled()
promise.then(onResolved[,onRejected])
这也是最常用,最重要的一个方法
方法then它有两个参数,
第一个参数onResolved,它代表Promise变成接受状态的时候调用的回调函数,
调用这个回调函数传递的实参,是最终异步操作接受的结果对象。
第二个参数onRejected,代表当Promise变成拒绝状态时调用的回调函数,
调用这个回调函数传递的实参,是拒绝的原因,一般是一个error对象,
promise.catch(onRejected)
第二个方法是catch,这个方法它是Promise处理拒绝情况的,
它相当于使用then方法同时设置onResolved与onRejected,
其中第一个参数onResolved传递undefined空值,只传递第二个,也就是第二个参数是有一个实际的值,
这种情况下就相当于是调用了catch这样的一个方法
promise。finally(onFinally)
用于设置无论Promise最终处于接受状态还是拒绝状态,都会执行的一个回调函数,
使用then这个方法,可能会在两种状态下写重复的处理代码。
这样无论什么状态都需要执行的代码,可以放在finally里面进行执行
Promise.all()
Promise.any()
Promise.race()
Promise.allSettled()
这四个方法都属于集合方法,代表将多个Promise实例,集合成一个新的Promise总实例,
并施加一种执行控制策略,这四个方法接受的参数都是一个数组,
数组的元素都是Promise实例。
all方法代表所有的Promise子实例,都必须处于接受状态,它才处于接受状态,否则就是拒绝在状态。
any代表任何一个子Promise实例变成接受状态,总实例即处于接受状态,而所有子实例都处于拒绝状态的时候,才处于拒绝状态。
race单词的中文意思是赛跑,代表个个Promise子实例的赛跑执行,
只要有任何一个子实例处于接受或者是拒绝的状态,总实例即处于接受或者拒绝状态
race与any的区别是它们对拒绝状态的处理策略不同
allSettled这个方法代表所有子实例无论处于接受状态或是拒绝状态,它们的状态都已经改变了才处于接受状态,
同时在回调函数中,返回一个包含所有子Promise实例状态的一个数组
联想一个之前我们提到过的一个多服务器IP连接场景,就适合使用any这种几个方法,
只要任何一个指向服务器的连接成功了,就算总实例连接成功了,同时这时候可以将其他连接全部abort掉,
而只有当所有连接都失败了,才算是总实例连接失败了
三、总结
这节课我们主要介绍了Promise以及介绍了Promise六个常用的方法。
下节课我们开始实践多个网络请求,并发执行的处理策略,
并着手将原来的登录代码模块,使用Promise的方式改写一下。