浅谈promise
基本概念
- promise是ES6新增的特性,主要是用来实现异步函数,减少回调爆炸(函数里面返回回调函数,依次不断返回)。
- promise具有三个不同状态值,分别是pendding(等待),fulfilled(成功),rejected(失败)。pendding能够转换成fulfilled,rejected两个状态值,但是fulfilled和rejected不能相互转换,也不能转换到pendding状态。
- 特别注意的是执行promis的构造函数时,此时执行的是主线程的任务,不存在异步问题按顺序执行。只用在函数中执行resolve()、reject()时候生成的promise对象调用then,catch才会被移入到微任务队列中。
可能大家对主线程任务、宏任务、微任务不太懂,当然了解的话可以跳过以下的解释啦。宏任务:定时器 setTimeout,setIntervel…,
微任务:process.nextTick,new Promise。一般主线程执行完毕以后,才会执行微任务,然后执行一个宏任务,检查是否还有微任务,执行完剩下的微任务,在执行剩下的宏任务。
⭐基本用法
let promise=new Promise((resolve,reject){
console.log("promxise构造函数形参是一个函数")
resolve("成功啦") //传递成z功结果,经过这个函数状态变成fulfilled
reject("失败啦") //传递成功结果,经过这个函数状态变成rejected
})
resolve和reject是在promise构造函数定义的属性,也是promise上的原型方法。
⭐then()
let promise=new Promise((resolve,reject){
console.log("promise构造函数形参是一个函数")
resolve("成功啦") //传递成功结果,经过这个函数状态变成fulfilled
reject("失败啦") //传递成功结果,经过这个函数状态变成rejected
})
promise.then(function fn1(value){
console.log(value) //
},function fn2(reason){
console.log(reason)
- 只有当promise构造函数中的resolve中返回了参数,then中value才不为空,reject一样道理。
- then的第一个参数的函数执行依赖于resolve是否执行,then的第二个参数的函数执行依赖于reject是否执行。
- .(同一个对象)如果resolve已经执行了,那么在末尾的reject就无法执行,在文章开始介绍过fulfilled和rejected不能相互转换,在上例中也只能显示成功了
其实resolve和reject只是一种传递参数方式,来完成异步操作
catch()
let promise=new Promise((resolve,reject)=>{
console.log("promise构造函数形参是一个函数")
resolve("成功啦") //传递成功结果,经过这个函数状态变成fulfilled
reject("失败啦") //传递成功结果,经过这个函数状态变成rejected
})
promise.then((value)=>{
console.log(value)//成功啦
}).catch((reason)=>{
console.log(reason) //失败啦
})
catch功能其实也就是相当于then的第二个函数,只不过catch优于then第二个参数的地方就是,一旦返回失败结果,如果是使用then的第二个参数接受那么就会卡死,而catch就不会。还有一种特殊情况如下:
let promise=new Promise((resolve,reject)=>{
console.log("promise构造函数形参是一个函数")
resolve("成功啦")
})
promise.then((value)=>{
throw new Error ("再次失败啦")
},(reason)=>{
console.log("我是then第二参数哦")
}).catch((reason)=>{
console.log(reason) //失败啦
console.log("我是catch哦",reason)
})
结果是:
promise构造函数形参是一个函数
Error: 再次失败啦
我是catch哦 Error: 再次失败啦
由此可知,当then第一个参数抛出的错误,then的第二参数是无法接收到的,只有catch才能捕获到then第一个参数抛出的错误哦
all()
let promise=new Promise((resolve,reject)=>{
resolve("成功啦")
})
let promise2=new Promise((resolve,reject)=>{
resolve("成功啦")
})
Promise.all([promise,promise2]).then(()=>{
console.log('都成功啦')//都成功啦
}).catch(()=>{
console.log("有一个或全部失败啦")
})
结果:都成功啦
Promise.all()的形参是一个数组,里面装的是promise对象。只有当数组里的promise对象全部完成之后才算成功,如果有一个失败了此时的状态就会变成了rejected
let promise=new Promise((resolve,reject)=>{
resolve("成功啦")
})
let promise2=new Promise((resolve,reject)=>{
reject("失败啦")
})
Promise.all([promise,promise2]).then(()=>{
console.log('都成功啦')//都成功啦
}).catch(()=>{
console.log("有一个或全部失败啦")
})
结果:有一个或全部失败啦
race()
let promise=new Promise((resolve,reject)=>{
resolve("成功啦")
})
let promise2=new Promise((resolve,reject)=>{
reject("失败啦")
})
Promise.race([promise,promise2]).then(()=>{
console.log("成功啦")
}).catch(()=>{
console.log("失败啦")
结果:成功啦
all是相当于大家要一起到达终点才算赢,算是团伙赛。而race就是个人赛,但凡有一个到达终点就算成功啦
基础讲解到此结束啦,文中可能有很多不足之处,大家可以多多指正。