文章目录
一、promise基本知识
- 回调函数
把函数当做参数进行传递,这个函数就是回调函数 - 回调地狱
下一次的结果必须借助上一次回调函数中返回的结果执行,这样的结构再多一些就是回调地狱。
$.ajax({
url:'http://www.wang.com/index.php/index/goods/userinfo',
method:'post',
data:{
username:'a123123'
},
success:function(res){
//2根据id获取订单信息
$.ajax({
url:'http://www.wang.com/index.php/index/goods/orderinfo',
method:'post',
data:{
id:res.info.user_id
},
success:function(orderres){
//3根据订单中商品id,获取商品·信息
$.ajax({
url:'http://www.wang.com/index.php/index/goods/goodsinfo',
method:'post',
data:{
id:orderres.info.goods_id
},
success:function(goodsres){
console.log(goodsres)
}
})
}
})
}
})
- 同步异步
(1)同步:等待上一个同步任务执行完毕,才执行下一个同步任务
(2)异步:等待所有同步任务执行完毕,再执行异步任务
eg: setTimeout() setInterval() ajax
二、promise对象
1.概念
- 理解:promise对象就是一个盒子
- 状态:
(1)pending(准备状态)->resolve()->fulfilled(成功状态)
(2)pending(准备状态)->reject()->rejected(失败状态) - 如何创健
let p=new Promise((resolve,reject)=>{
})
2.使用
A.then()获取成功的状态结果
then方法中可以继续return一个promise对象,然后返回值就是这个promise对象。
function p1(){
let p = new Promise((resolve,reject) => {
setTimeout(() => {
resolve({a:1,b:2})
},1000)
})
return p;
}
function p2(){
let p = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('hello world')
},1000)
})
return p;
}
p1().then((res) => {
return p2();
}).then((res) => {
console.log(res)
}).catch((err) => {
console.log("err",err)
})
B. catch()获取失败的状态结果
在一个链式操作中,不管哪一个环节出错,catch方法都可以捕获到,所以只写一次就行了。
let p = new Promise((resolve,reject) => {
setTimeout(() => {
reject({a:1,b:2})
},1000)
})
p.then((res) => {
console.log("res",res)
}).catch((err) => {
console.log("err",err)
})
C.并发请求Promise.all()
语法:Promise.all([promise实例1,promise实例2…]).then().catch()
执行特点:只有三个promise实例的状态都确定为成功时,promise.all的最终状态才是成功;只要有一个出现错误,Promise.all()的状态就会变成失败。
如何避免一个错最终错
给每个请求实例写上单独的catch!
D. Promise.race()
同时执行多个实例,哪个先确定状态,race方法就以那个状态为主
E. Promise.allSettled([实例])
并发去执行多个实例,但是就算有实例失败,也会进入到allSettled的成功方法中去(then)
三、async/await
1.发展
在解决异步问题的时候,最开始的方法就是回调函数,后来除了promise盒子去帮助咱们解决回调地狱的问题。但是,promise感觉还是不够好用,开发者就开始思考,如果能将异步异步任务当做同步任务去执行,那应该多舒服啊。因为有这个思考,所以开发者开始去尝试,中途出现了一个新的技术叫做:generotor函数,已经比较舒服的可以去解决异步问题了,但是还不够完美,随着技术的发展,最终演变成了两个关键词:async await
2.async
专门用来修饰函数,将函数变成一个promise对象
- 变成promise对象
let say = async () => {
}
let res = say();
console.log(res)
- 函数return的结果就是promise对象resolve的结果
3.await
用来修饰任何一个数据,但是,咱们只会让他去修饰一个promise对象。
特性:
- 他修饰promise对象,可以让进程等待这个promise对象确定最终状态
- 必须用在 async 修饰的函数中
- await 的返回值:就是await修饰的promise盒子的resolve值
4.关于错误
-
如果你的async函数中,除了被等待的promise以外,没有其他的逻辑,或者其他逻辑必须借助promise的结果,那么你就直接在async函数的catch中去捕获错误
-
被等待的promise的结果不会对我的其他逻辑造成影响
5.解决回调地狱
function getuserinfo(username){
return new Promise((resolve,reject)=>{
$.ajax({
url:'http://www.wang.com/index.php/index/goods/userinfo',
method:'post',
data:{
username:username
},
success:function(res){
resolve(res)
},
error:function(err){
reject(err)
}
})
})
}
function getorderinfo(userid){
return new Promise((resolve,reject)=>{
$.ajax({
url:'http://www.wang.com/index.php/index/goods/orderinfo',
method:'post',
data:{
id:userid
},
success:function(res){
resolve(res)
},
error:function(err){
reject(err)
}
})
})
}
function getgoodsinfo(goodsid){
return new Promise((resolve,reject)=>{
$.ajax({
url:'http://www.wang.com/index.php/index/goods/orderinfo',
method:'post',
data:{
id:goodsid
},
success:function(res){
resolve(res)
},
error:function(err){
reject(err)
}
})
})
}
getuserinfo('a123123').then((res)=>{
return getorderinfo(res.info.user_id)
}).then((res)=>{
return getgoodsinfo(res.info.goods_id)
}).then((res)=>{
console.log('成功',res)
}).catch((err)=>{
console.log('失败',err)
}).finally(()=>{
console.log('all')
})