回调地狱
- 回调函数:函数的结果被传入到另一个函数中当做实参
- 回调地狱:回调里套回调
- 特点:发送多次ajax请求 后一次请求要依赖于上一次请求的结果
(此案例接口只供自己使用,勿复制,可参考逻辑)
1.回调地狱案例
案例调用接口获取第一个省份的第一个城市列表(axios插件)
axios.defaults.baseURL='http://ajax-api.net' //基地址
axios.get('/api/province').then(res=>{
//获得第一个省份的名字,再查询这个省份下的城市
const pname=res.data.data[0]
axios.get(`/api/city?pname=${pname}`).then(res=>{
//获取查询省份的第一个城市
const cname=res.data.data[0]
//获取城市下的县区信息
axios.get(`/api/area?pname=${pname}&cname=${cname}`).then(res=>{
console.log(res.data.data);
})
})
})
此处后一个请求的省份名、城市名、县级信息都要依赖上一次响应的结果,会发送多次ajax请求
then()是一个函数,里面套了多层回调函数,此处体现出了回调地狱
2.promise优化回调地狱
首先要知道axios(url:‘’,method:‘GET’)能简写为:axios.get(‘url’) 且返回值为promise对象,如下:
console.log(axios.get('http://ajax-api.net/api/province'))
结果如下:是个promise对象类型
promise对象的值可以用axios.get().then(res=>{}) then()函数接收,res就为axios.get()返回正确的值,那我们可以用.then()里return Promise对象结果会被链式调用下一个then接收特性来优化1中的回调地狱案例
// 使用Promise的链式调用解决问题
// axios函数在原地返回的就是一个Promise对象
let pname = ''
axios.get('http://ajax-api.net/api/province').then(res => {
// 2. 获取第一个省, 对应的城市列表
pname = res.data.data[0];
return axios.get(`http://ajax-api.net/api/city?pname=${pname}`)
}).then(res => {
// 3. 获取第一个市, 对应的地区列表
let cname = res.data.data[0]
return axios.get(`http://ajax-api.net/api/area?pname=${pname}&cname=${cname}`)
}).then(res => {
console.log(res);
})
3.async,await优化回调地狱
-
其实.then后, 也不便于阅读, 不太直观知道return返回到下一个then去使用 。所以, ES8新出了关键字async和await尝试解决这个问题
-
async,await语法:
async function 函数名() {
const result = await Promise对象
// 拿到Promise对象内成功的结果继续向下执行
}
- 说白了,async,await取代then函数,来获取promise的值
因此,我们可以通过async,await获取值并给下一个请求使用,我们用async,await来优化1中的回调地狱案例
// async,await优化回调地狱
axios.defaults.baseURL = "http://ajax-api.net"
async function fn() {
const province = await axios.get("/api/province")
const pname = province.data.data[0]
console.log(pname)
const cities = await axios.get(`/api/city?pname=${pname}`)
const cname = cities.data.data[0]
console.log(cname)
const areas = await axios.get(`/api/area?pname=${pname}&cname=${cname}`)
return areas.data.data //是promise对象
}
// promise对象获取值再次使用async,await
async function f() {
const f = await fn()
console.log(f)
}
f()
//.then()也可以获取,如下:
// fn().then(res=>{
// console.log(res);
// })
工作中主要用async,await 来解决回调地狱