Promise
1、new Promise函数体内是同步,then和cach是异步
2、Promise在声明的时候就执行了
3、promise有三种状态:Pending(进行中)、Resolved(成功)、Rejected(失败)
4、成功必须调用resolve(),.then才会执行,不然一直在pending状态不往下走
5、失败必须调用reject(),.catch才会执行,不然一直在pending状态不往下走
6、promise支持链式调用,可以解决回调地狱问题
Promise普通例子
1、创建一个Promise实例,获取数据,并把数据传递给处理函数resolve和reject。
const p = new Promise( (resolve, reject)=>{
console.log(’pending‘) //同步
resolve(' 成功! ') //resolve返回的值是then返回值的形参 pending => fulfilled
// reject(' 失败! ') //reject返回的值是catch返回值的形参 pending => rejected
// throw ' 错误' // 也是走rejected pending => rejected
})
p.then(res=>{ // Rejected(成功状态)
console.log(’res, 成功返回 ‘ )
},err=>{ //Resolved(失败状态)
// 和catch是一样,catch是then封装出来的
console.log(err,’ 失败返回1 ‘ )
})
//打印顺序:pending、成功!、成功返回
//打印顺序:pending、失败!、失败返回1
//打印顺序:pending、失败!、失败返回
console.log(p) //可以查看promise,打印在pending后面,同步
3.Promise异步任务
const p1 = new Promise((resolve,reject)=>{
setTimeout(()=> { resolve('ok') },1000)
// setTimeout(()=> { reject('err') },1000)
})
p1.then(res=>{
console.log(res) // ok
},err=>{
console.log(err) // err
})
Promise创建方式
1、创建成功Promise对象
const p1 = new Promise((resolve,reject)=>{ resolve('ok') })
Promise.resolve('ok')
Promise.resolve( new Promise((resolve,reject)=>{ reject('ok') }) ) //会将内部的promise错误值返回
//返回一个新的(成功的)promise对象:PromiseState:{ PromiseState:'fulfilled', PromiseResult:'ok' }
2.创建失败Promise对象
const p1 = new Promise((resolve,reject)=>{ reject('err') })
Promise.reject('err')
Promise.reject( new Promise((resolve,reject)=>{ resolve('err') }) )
//返回一个新的(失败的)promise对象:PromiseState:{ PromiseState:'rejected', PromiseResult:'err' }
Promise.all([])
1、参数为数组,每个元素都为Promise对象
2、成功all:3个都成功,则返回3个promise返回值的数组(新的promise)
3、失败all:有一个promise失败就返回失败的promise的值(新的promise)
const p1 = new Promise((resolve,reject)=>{
resolve({name:'tom',age:19})
})
const p2 = Promise.resolve('成功数据1111')
const p3 = Promise.resolve(new Promise((resolve,reject)=>{
resolve([1,2,3,4])
}))
const p4 = Promise.resolve(new Promise((resolve,reject)=>{
reject({msg:'error',code:404})
}))
const p5 = new Promise((resolve,reject)=>{
setTimeout(()=>{ resolve('ok') },1000)
})
// ***成功all***
const result = Promise.all([p1,p2,p3])
// 返回新的promise 值为3个promise值组成的数组:[{name:'tom',age:19}, '成功数据1111', [1,2,3,4] ]
// ***失败all***
const result = Promise.all([p1,p4,p3])
// 返回新的promise 值为错误的promise值:{msg:'error',code:404}
Promise.race([])
1、返回新的promise对象,根据第一个promise状态来,成功就成功,失败就失败
2、如果第一个加了计数器需要等待,就按第二个promise状态来定
//成功(同步任务)
const result3 = Promise.race([p1,p2,p3]) // {name:'tom',age:19}
//失败(同步任务)
const result4 = Promise.race([p4,p2,p3]) //{msg:'error',code:404}
//成功(异步任务)
const result5 = Promise.race([p5,p2,p3]) // 成功数据1111
Promise解决回调地狱
当一个接口的参数会需要使用另一个接口的返回值,可以把一个接口写在另一个接口的返回值里。但是,如果需要的是另外好几个接口的返回数据呢?。这就是回调地狱!
解决方案():1、promise链式调用;
1、通过promise链式调用解决回调地狱。
function getData(path){
return new Promise((resolve,reject)=>{
axios.post(path).then(res=>{
resolve(res)
},err=>{
reject(err)
})
})
}
getData('/iyw/getToken').then(res=>{
console.log(res)
return getData('/iyw/getUserInfo')
}).then(res=>{
console.log(res)
return getData('/iyw/getList')
}).then(res=>{
console.log(res)
return getData('/iyw/getDetails')
}).then(res=>{
console.log(res)
}).catch(err=>{
console.log(err) //捕获接口错误
})
async
1、给函数前加async,改函数就会返回一个promise对象
async function main(){
return 124; //如果返回值是一个非Pormise类型的数据,
return new Promise((resolve,reject)=>{ //如果返回值是一个Pormise对象
resolve('ok')
})
}
const m = main()
console.log(m) //promiase对象
await
1、await右侧一般为promise对象、其他值
1)promise对象(resolve):返回promise成功值
2)其它值:直接返回其它值
3)promise对象(reject):当promise失败,就会抛出异常,可以通过try..catch捕获promise失败值
2、await必须写在async函数里,但async函数中可以没有await
async function main2(){
// 1、右侧为其它值
const res = await false;
// 2、右侧为promis对象 --成功
const res2 = await new Promise((resolve,reject)=>{ resolve('success1111') })
console.log(res,res2) // false success1111
// 3、右侧为promis对象 --失败(通过try...catch捕获)
try{
var res3 = await new Promise((resolve,reject)=>{ reject('error1111') })
}catch(e){
console.log(e) //error1111
}
}
main2()
例子:
async function fun1() {
let data = await fun2()
console.log(data) //then中执行的代码
}
async function fun2() {
console.log(22) //同步的
return 11
}
//打印:22、11
async + await
1、try有一个报错就会走catch,并将错误数据返回
async function main3(){
try{
const res1= await Ajaxs('https://api.apiopen.top/getJoke')
const res2= await Ajaxs('https://api.apiopen.top/getJoke1')
const res3= await Ajaxs('https://api.apiopen.top/getJoke')
console.log(JSON.parse(res1).message,'----1---') //成功! ----1---
console.log(JSON.parse(res2).message,'----2---') //成功! ----2---
console.log(JSON.parse(res3).message,'----3---') //成功! ----3---
}catch(e){
console.log(e.code) // 404
}
}
main3()
Promise链式任务 + catch异常穿透 + 中断promise链条
1、promise链? :就是一直.then .then...下午
1、异常穿透():不管promise链式回调哪个promise抛出异常catch都能捕获到
2、 中断promise链式():只有一种方法就是返回一个pending状态的promise (new Promise(()=>{}))
let p = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('ok') },1000) }) //1秒后执行
p.then(res=>{
console.log(res) // ok
return new Promise((resolve,reject)=>{
resolve('success')
//reject('error') 抛出错误,catch就能异常穿透捕获到错误状态
})
}).then(res=>{
console.log(res) // success
return false
}).then(res=>{
console.log(res,11) // false 11
return new Promise(()=>{}) //中断promise链()----------
}).then(res=>{
console.log(res,22) // undefined
}).then(res=>{
console.log(res,33) // undefined
}).then(res=>{
console.log(res,44) // undefined
}).catch(err=>{
console.log(err) //error 异常穿透可捕获promise链中任意错误的promise值
})
promise加载顺序
习题:
// 1 3 5 8 2 6 7 4
console.log(1)
async function main1(){
await mian2()
console.log(2) //微任务,then
}
async function main2(){
console.log(3) // 这也是promise函数体
}
main1()
setTimeout(()=>{console.log(4)},0)
new Promise((resolve)=>{
console.log(5)
resolve() //加这个,promise才会走then方法
}).then(()=>{
console.log(6)
}).then(()=>{
console.log(7)
})
console.log(8)