文章目录
promise是什么
日常开发中,异步操作几乎每天都能见到。传统的意不解决方案是通过回调函数,随着程序逻辑越来越复杂,回调函数的方式变得越来越繁琐,很容易出现回调地狱,于是一种更合理更强大的代替方案出现–Promise
promise是异步编程的一种解决方案,指定回调函数的方式更加灵活。
支持链式调用,可以解决回调地狱问题
定义:
Promise 对象用于表示一个异步操作的最终完成 (或失败), 及其结果值.
语法:
new Promise( function(resolve, reject) {...} /* executor */ )
状态
- pending: 初始状态,既不是成功,也不是失败状态。
- fulfilled: 意味着操作成功完成。
- rejected: 意味着操作失败。
一旦状态改变,就不会再变,任何时候都可以得到这个结果。
方法
- then()
当实例发生改变时的回调函数,返回的是一个新的promise实例,这也是promise能链式书写的原因
const p = new Promise((resolve,rejected)=>{
resolve('成功的数据') //成功的方法,改变promise状态为成功
rejected('失败的数据') //失败的方法,改变promise状态为失败
})
p.then(value=>{ //成功状态的调用方法
console.log(value)
},reason=>{ //失败状态的调用方法
console.log(reason)
})
- catch()
错误处理,用于指定发生错误的回调函数,常用catch()方法替代then()里面的第二个参数
const p = new Promise((resolve,rejected)=>{
resolve('成功的数据') //成功的方法,改变promise状态为成功
rejected('失败的数据') //失败的方法,改变promise状态为失败
})
p.then(value=>{ //成功状态的调用方法
console.log(value)
}).catch(value=>{ //错误处理用来替代then方法的第二个参数
console.log(value)
})
- finally()
用来指定不管promise对象状态最后如何都会执行的操作
const p = new Promise((resolve,rejected)=>{
rejected('失败的数据') //失败的方法,改变promise状态为失败
})
p.then(value=>{ //成功状态的调用方法
console.log(value)
}).catch(value=>{ //
console.log(value)
}).finally(()=>{
console.log('finally操作')
})
- all()
将多个promise实例包装成一个新的promise实例,所有promise实例执行成功,则成功
function p1(){
return new Promise((resolve,rejected)=>{
setTimeout(()=>{
resolve('p1')
},1000)
})
}
function p2(){
return new Promise((resolve,rejected)=>{
setTimeout(()=>{
resolve('p2')
},2000)
})
}
function p3(){
return new Promise((resolve,rejected)=>{
setTimeout(()=>{
resolve('p3')
},3000)
})
}
const pAll = Promise.all([p1(),p2(),p3()])
pAll.then(value=>{
console.log(value)
}).catch(value=>{
console.log(value)
}).finally(()=>{
console.log(pAll)
})
pAll 的状态由p1,p2,p3决定,只有当三个都为成功时,pAll状态才为成功
function p1(){
return new Promise((resolve,rejected)=>{
setTimeout(()=>{
resolve('p1')
},1000)
})
}
function p2(){
return new Promise((resolve,rejected)=>{
setTimeout(()=>{
rejected('p2')
},2000)
})
}
function p3(){
return new Promise((resolve,rejected)=>{
setTimeout(()=>{
rejected('p3')
},3000)
})
}
const pAll = Promise.all([p1(),p2(),p3()])
pAll.then(value=>{
console.log(value)
}).catch(value=>{
console.log(value)
}).finally(()=>{
console.log(pAll)
})
如果其中有一个为失败,pAll状态为失败,并且返回第一个失败实例的值为pAll 的值
function p1(){
return new Promise((resolve,rejected)=>{
setTimeout(()=>{
resolve('p1')
},1000)
})
}
function p2(){
return new Promise((resolve,rejected)=>{
setTimeout(()=>{
rejected('p2')
},2000)
}).catch(value =>{
console.log('p2异常处理')
})
}
function p3(){
return new Promise((resolve,rejected)=>{
setTimeout(()=>{
resolve('p3')
},3000)
})
}
const pAll = Promise.all([p1(),p2(),p3()])
pAll.then(value=>{
console.log(value)
}).catch(value=>{
console.log(value)
}).finally(()=>{
console.log(pAll)
})
如果作为参数的实例自己定义了catch方法,那么他出现失败结果不会影响pAll状态,但其值为undefined
[‘p1’, undefined, ‘p3’]
function p2(){
return new Promise((resolve,rejected)=>{
setTimeout(()=>{
rejected('p2失败数据')
},2000)
}).catch(value =>{
return value
})
}
则可以获取到p2 失败数据 [‘p1’, ‘p2失败数据’, ‘p3’]
- race()
将多个promise实例包装成一个新的promise实例
function p1(){
return new Promise((resolve,rejected)=>{
setTimeout(()=>{
resolve('p1')
},1000)
})
}
function p2(){
return new Promise((resolve,rejected)=>{
setTimeout(()=>{
resolve('p2')
},2000)
})
}
function p3(){
return new Promise((resolve,rejected)=>{
setTimeout(()=>{
resolve('p3')
},3000)
})
}
const pRace = Promise.race([p1(),p2(),p3()])
pRace.then(value=>{
console.log(value)
}).catch(value=>{
console.log(value)
}).finally(()=>{
console.log(pRace)
})
pRace 区别与 pAll 只要有一个实例先改变状态,就会把这个实例的返回值传给pRace的回调函数
一个有意思的小练习:发送请求,请求全部成功返回成功,不成功继续把没成功的请求继续发送,执行几次后还是失败就返回请求失败。
//发送请求
function p(num) {
return new Promise((resolve, rejected) => {
setTimeout(() => {
if (num > 2) {
resolve('成功')
} else {
rejected('失败')
}
}, 1000)
}).then(value => {
return false
}).catch(value => {
return true
})
}
//参数
let params = [1, 2, 3, 5]
//存储返回值
let arr = []
//循环参数 发送请求
for (let item of params) {
arr.push(p(item))
}
send(arr, 0, params)
//判断请求是否成功
function send(promiseArr, stop, params) {
if (stop >= 4) {
alert('失败')
return false
}
stop++
console.log('stop: ' + stop)
const pAll = Promise.all(promiseArr)
pAll.then(value => {
console.log(value)
let valuearr = []
value.forEach((item, index) => {
//判断是否有失败的
if (item) {
valuearr.push(
p(params[index])
)
}
})
//判断还有没有失败的
if (valuearr.length) {
send(valuearr, stop, params)
}else{
alert('成功')
}
})
}
- allSettled()
将多个promise实例包装成一个新的promise实例,所有promise实例执行完成后,则成功(不论里面promise是否成功)