为什么使用Promise
Promise是异步编程的一种解决方案,比传统的回调函数和事件,更加合理和强大。
有没有遇到过这种需求,一个请求完毕后才能发起另一个请求。这样的话另一个请求就要嵌套进前一个请求中了,一个两个还好,但想象下要是有四五个呢,那代码将会变得非常难看和难以维护(回调地狱)。而promise的出现正是要解决这个问题的。
1、Promise的原理:
Promise本身是ES6的一个内置类(注意它的开头字母大写),而它的作用就是保存一个异步操作,并提供相关的api去获取其异步操作的结果和设置多个异步操作间的顺序(注意异步操作本身是无序的,只不过是Promise对象在内部实现了的嵌套和其他的相关方法使异步操作达到有序的现象)。
2、Promise对象的两个特点
2.1 Promise对象状态不受外界影响
Promise有三种状态,Pending、Fulfilled、Rejected,只有异步操作的结果可以决定当前是哪一种状态,其他任何操作都改变不了当前的状态。
2.2 一旦状态改变便不会再变
Promise对象状态改变只有两种情况:从Pending变为Fulfilled、从Pending变为Rejected这两种。
3、Promise语法
let arr = true
let a = new Promise((resolve,reject) => {
// 逻辑判断
setTimeout(() => {
if (arr) {
resolve(true)
} else {
reject(false)
}
}, 500);
}).then((res) => res)
.catch(reason => reason)
3.1 Promise对象是一个构造函数
用来生成Promise实例,Promise构造函数接受一个函数作为参数,函数的两个参数resolve和reject,用于处理异步方法的成功和失败返回。
3.2 then方法
分别指定resolve和reject的返回
Promise.then((val) => {
// success
}, (reason)=> {
// failure
})
一般来说,不要在then方法中定义Rejected状态的回调函数,即then的第二个参数,而总使用catch方法。
3.3 catch方法
catch方法用于指定发生错误时的回调函数
4、Promise.all方法
Promise.all方法将多个Promise实例包装成一个新的Promise实例
let pro1 = new Promise((resolve,reject) => {
resolve(1)
}).then((res)=>res)
let pro2 = new Promise((resolve,reject) => {
resolve(2)
}).then(res => res)
Promise.all([pro1,pro2])
.then(([res1, res2]) => {
console.log(res1)
console.log(res2)
})
4.1 数组作为参数
上面代码中,数组作为参数,pro1和pro2都是Promise对象的实例,
Promise.all的状态由pro1和pro2决定:
- pro1和pro2状态都变成Fulfilled, all的状态才变成Fulfilled,此时pro1和pro2的返回值组成一个数组,传递给all的回调函数
- 只要pro1和pro2有一个reject,all的状态就变成rejected,此时第一个reject的实例的返回值会传递给all的回调函数。
4.2 Promise.all的catch
如果作为参数的Promise实例,自定义了catch方法,那么reject时不会触发Promise.all的catch方法。
5、Promise.race
Promise.race方法语法与Promise.all一致,区别在于:
Promise.race作为参数的实例,有一个率先改变状态,Promise.race就跟着改变。
6、Promise.done方法
Promise.done方法可以和then方法一样使用,但done方法总处于回调链尾端,捕捉任何可能出现的错误,并向全局抛出。
Promise.all([a, b, c])
.then( (res) => {
return res.some((val) => {
val == true
})
})
.catch()
.then()
.done()
7、Promise.finally方法
Promise.finally不管Promise对象最后的状态如何都会执行,接受一个普通的回调函数作为参数,该函数不管如何都会执行
server.listen(0)
.then()
.finally(server.stop)
例如上面的逻辑,服务器使用Promise处理请求,然后使用finally方法关掉服务器。