Promise
使用
1.首先明确promise是一个构造函数,即可以实例化,使用new关键字
let pro = new Promise((resolve,reject)=>{
// 这里面可以操作一些异步函数
})
参数说明
resolve: 当我们的异步操作成功的时候,我们可以调用这个参数,首先明确,这个参数是一个函数,
reject:当我们异步操作失败的时候,可以调用这个参数,这个参数一样是一个函数,
作用
这两个函数参数的作用都是修改promise的状态,如果我们调用了resolve,那么promise的状态就修改为成功(fulfill),否则,调用rejecte,就修改为失败状态(reject),当然这两个函数里面也是可以传递参数的,这个参数的传递可以被以下的.then的两个函数参数所接受。
完整使用:
案例说明:当我们的随机数产生的时< 30 的数时,我们就成功,否则就失败。成功弹出成功的alter,失败弹出失败的alter
let p = new Promise((resolve, reject) => {
setTimeout(() => {
// 产生随机数
let num = Math.floor(Math.random() * 100);
// 如果随机数小于三十,那么就是中奖,修改promise的状态
if (num < 30) {
resolve(num);
} else {
reject(num);
}
}, 1000)
})
// 成功与失败的操作放于此
p.then((value) => {
// 成功状态时要做什么
alert(‘恭喜你!’ + value)
}, (val) => {
// 失败的状态要做什么
alert(‘很遗憾’ + val)
})
}
.then 与 .catch
.then
当我们发起异步操作后,调用resolve与reject函数,会修改promise的状态,那么就会分为失败与成功的状态,.then()这个函数都可以接受,注意.then方法的参数也都是函数,第一个参数是成功状态时执行的,第二个参数是失败时执行的。且在我们的状态修改成成功/失败时,才会执行.then()方法
一句话总结就是把如果promise是成功/失败的状态我们要做什么都放在里面
pro.then(()=>{
//状态为成功时,可以在这边做一些操作
}
,()=>{
// 状态为失败时,可以在这里做一些操作
})
.catch
与.then不同的是只接受一个参数,且也是函数,只有当我们的状态是失败的时候,才会执行改该函数.
注意:我们的catch是一个基于then的一个封装,当我们的then有两个参数,即我们的then接受了失败的参数,那么.catch就不会执行。
pro.then((res)=>{}).catch((err)=>{})
promise的状态与结果.
状态三个
属性参数 [PromiseState]
1.pending : 未确定态,证明改异步函数还仍然在请求中
2.fullfille : 成功状态 , 即请求成功返回的状态
3.rejected:失败状态 ,即请求失败返回的状态
状态之间的转换: 注意只有resolve与rejected函数与throw(只能抛出错误)可以进行状态的修改。像.then这种是不行的。且起始的状态是pending
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ek9AKdpr-1667012940371)(C:\Users\机智聪慧的人\AppData\Roaming\Typora\typora-user-images\image-20221028155601581.png)]
结果
属性参数是 [[PromiseResult]]
里面保存着成功/失败的返回的结果,且只有resolve(val),与reject(val)这两个函数可以修改里面的值,在.then()里拿出来做出操作
Promise.resolve与Promise.reject
注意:这里这两个函数与上边的resolve与reject不同,他们俩不是实例里面的,是Promise这个函数里面的,作用也不同
这两的返回值都是一个Promise对象,只是状态不一样的Promise对象
Promise.resolve
它返回的promise对象是哪种状态,决定于参数的状态,如果它的参数不是一个Pormise实例,那么就一定会返回成功状态的promise对象,如果是promise实例,那么就决定于这个实例的状态是否是成功的,如果是成功的状态,那么就返回成功状态的promise对象,否则就返回一个失败的promise对象。
Promise.reject
一定是返回一个失败的Promise对象,不管是传入什么参数
let p = Promise.resolve(new Promise((resolve, reject) => {
resolve(123);
})) // p为成功的,如果调用reject那么就是失败的状态
let p = Promise.reject(new Promise((resolve, reject) => {
resolve(123);
})) // 返回一个失败的对象,不管它是什么,结果是这个new Promise的结果(注意不管这个实例是成功还是失败都是这个结果。)
Promise.all 与Promise.race
Promise.all
当里面的所有promise实例都返回一个成功状态时,那么返回值就是一个[PromiseResult]是一个数组的Promise对象,且状态是fulfilled,数组里面存放了这些所有成功状态实例的返回结果,即resolve(n)里面的n,
let p1 = new Promise((resolve, reject) => {
resolve(‘p1的结果’);
})
let p2 = new Promise((resolve, reject) => {
resolve(‘p2的结果’);
})
let p3 = new Promise((resolve, reject) => {
resolve(‘p3的结果’);
})
let p = Promise.all([p1, p2, p3]);
console.log§;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0g1g70dm-1667012940372)(C:\Users\机智聪慧的人\AppData\Roaming\Typora\typora-user-images\image-20221028165037024.png)]
当里面的promise实例有一个是失败,或多个是失败的状态时,那么就只返回第一个失败状态的promise实例对象的结果,且他自己的promise状态是rejected。
let p1 = new Promise((resolve, reject) => {
resolve(‘p1的结果’);
})
let p2 = new Promise((resolve, reject) => {
reject(‘p2的结果’);
})
let p3 = new Promise((resolve, reject) => {
reject(‘p3的结果’);
})
let p = Promise.all([p1, p2, p3]);
console.log§;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3FW5GhcF-1667012940373)(C:\Users\机智聪慧的人\AppData\Roaming\Typora\typora-user-images\image-20221028165403530.png)]
Promise.race
返回的是最先返回的那个promise实例。如果最先返回的实例状态是成功,那么他的Promise对象就是成功否则就是失败,且返回的[PromiseRuslt]也是最先返回实例的result
Promise 执行顺序
情况一:当new promise里面是一个同步任务的时候
那么是先改变状态,再执行.then这种回调函数
情况二:当 new promise里面是一个异步任务的时候
那么就是先指定回调函数,再改变状态,即.then方法先初始化,注意.then里面的逻辑运算要等待promise的状态改变的时候,才会执行。
.then
const p = new Promise((resolve,reject)=>{ });
const result = p.then(res=>{},err=>{});
.then的返回结果是一个新的Promise对象,这个新的promise对象的状态与返回的结果取决于他的回调函数,就是 .res=>{} 或者是 err=>{}来决定。
情况一:回调函数里面的返回值是一个非promise。那么就是成功的状态,结果就是return的结果
情况二:回调函数里面返回的是一个promise对象,那么状态与结果就取决于这个promise函数。
例:
const p = new Promise((resolve,reject)=>{
resolve(‘成功消息’)
})
const res = p.then(res =>{ return new Promise((resolve,reject)=>{ resolve(‘then成功’) }) }, err =>{})
// 那么这时,res返回的就是一个成功的promise对象
小例题:
const p = new Promise((resolve,reject)=>{
resolve(‘成功消息’)
})
p.then(res =>{
return new Promise((resolve,reject)=>{ resolve(‘then成功’) })
}, err =>{}).then(res=>{
console.log(res); // ‘then成功’
}).then(res=>{
console.log(res); // undefined , 由于上一层没给它返回一个值,那么就是undefined
})
异常穿透
白话说就是
const p = new Promise((resolve,reject)=>{
resolve(‘成功消息’)
})
p.then(res =>{
throw ‘抛出一个错误’
}, ).then(res=>{
}).then(res=>{
}).catch(err=>{
console.log(err)
})
这个就是异常穿透,当第一个then抛出异常时,后面的两个then方法都不会再执行,直接到达.catch方法进行执行,那俺么就是异常穿透啦
promise链
白话文就是,不断.then().then().then的问题,如以上的代码,就是promise链。
想要中断着这种promise链,那么有且只有一种方式,就是返回一个pending状态的promise对象。其他返回啥都不好使。
p.then(()=>{
return new Promise(()=>{});
})
作用
1.支持链式调用,解决回调地狱的问题,
回调地狱:就是一个回调函数当中,嵌套另一个异步任务,无线套娃的方式,就形成了回调地狱。(扩展:当我们不使用promise来解决这种异步问题时,我们需要监测异步操作什么时候返回一般都是使用回调函数的方式实现的 ,如 fs.readFile(‘./1.txt’,(err,data)=>{}) )
2.指定回调函数更加的灵活