简单介绍:
Promise,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大
状态
promise对象仅有三种状态:
- pending(进行中)
- resolve/fulfilled(已成功)
- reject(已失败)
Promise对象特点
- 对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending、resolve和reject。只有异步操作的结果,可以确定当前是哪一种状态,其他操作都无法改变这个状态。
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为reject。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。
- 有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
Promise实例方法
Promise构建出来的实例存在以下方法:
- then(); 2. catch(); 3. finally()
1.then()
then是实例状态发生改变时的回调函数,第一个参数是resolve状态的回调函数,第二个参数是reject状态的回调函数;then方法返回的是一个新的Promise实例,也就是promise能链式书写的原因
2. catch()
catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数
3. finally()
finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作
//多层回调
new Promise((resolve, reject) => {
resolve(666)
console.log('padding 进行中');
}).then(res => {
return new Promise(resolve => {
console.log(res);
resolve(555)
})
}).then(res => {
return new Promise(resolve => {
console.log(res);
resolve(444)
})
}).then(res => {
return new Promise((resolve, reject) => {
console.log(res);
// reject(333)
resolve(222)
})
}).then(res=>{
console.log(res+'接受');
}).catch(err=>{
console.log(err+"拒绝");
}).finally(res=>{
console.log('所有状态中最后一个执行');
})
执行结果:
padding 进行中
666
555
444
222接受
所有状态中最后一个执行
Promise构造函数存在以下方法:
all()
race()
allSettled()
resolve()
reject()
try()
any()
下面以all()方法为例简单介绍一下
all()
Promise.all()同时监听多个promise实例的状态变更
let p = Promise.all([p1, p2, p3]);接受一个数组作为参数,其中数组全部成员都应为Promise实例只有p1,p2和p3的状态都变成resolve,p的状态才会变成resolve,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数;只要p1、p2、p3之中有一个状态为reject,那么p的状态就变成reject,此时第一个被reject的实例的返回值,会传递给p的回调函数
注意点,如果作为参数的 Promise 实例即p1, p2, p3,自己定义了catch方法,那么它一旦被rejecte,并不会触发Promise.all()的catch方法
let p1 = new Promise((resolve, reject) => {
console.log('run p1');
setTimeout(() => {
resolve("p1 sucess")
}, 800)
})
let p2 = new Promise((resolve, reject) => {
console.log('run p2');
setTimeout(() => {
resolve('p2 sucess')
}, 500)
})
let p3 = new Promise((resolve, reject) => {
console.log('run p3');
setTimeout(() => {
resolve("p3 sucess")
}, 1000)
})
var task = [p1, p2, p3]; //任务数组
var p = Promise.all(task)
p.then((res) => {
console.log('all run', res);
})
p.catch(res=>{
console.log('run catch');
console.log(res);
})
执行结果:
run p1
run p2
run p3
all run Array(3)0: "p1 sucess"1: "p2 sucess"2: "p3 sucess"length: 3[[Prototype]]: Array(0)
Promise优缺点
优点:
让回调函数变成了规范的链式写法,程序流程可以看的很清楚。他有一整套接口,可以实现许多强大的功能,比如同时执行多个异步操作,等到他们的状态都改变以后,在执行一个回调函数;再比如,为多个回调函数中抛出的错误,统一制定处理方法。
缺点:
编写的难度比传统写法高,而且阅读代码也不是一眼可以看懂。
promise两个缺点,一个是一旦开始执行就无法取消,第二个就是无法进度追踪