1.async await优化回调地狱代码
<script src="https://cdn.jsdelivr.net/npm/axios@0.27.2/dist/axios.min.js"></script>
<script>
// 目标: 使用Promise的链式调用解决问题
// 前提: axios函数在原地返回的就是一个Promise对象
// let pname = ''
// axios.defaults.baseURL = 'http://ajax-api.itheima.net'
// axios.get('/api/province').then(res => {
// // 2. 获取某个省, 对应的城市列表
// pname = res.data.data[5];
// return axios.get(`/api/city?pname=${pname}`)
// }).then(res => {
// // 3. 获取某个市, 对应的地区列表
// let cname = res.data.data[0]
// return axios.get(`/api/area?pname=${pname}&cname=${cname}`)
// }).then(res => {
// console.log(res);
// })
</script>
<script>
// async function f1(){
// return [1,2,3]
// }
// const res = f1()
// console.log(res)
axios.defaults.baseURL = 'http://ajax-api.itheima.net'
async function fn(){
const provinces = await axios.get('/api/province')
const pname = provinces.data.data[5];
const citys = await axios.get(`/api/city?pname=${pname}`)
let cname = citys.data.data[0]
const areas = await axios.get(`/api/area?pname=${pname}&cname=${cname}`)
// console.log(areas.data.data)
return areas.data.data
}
async function f (){
const t = await fn()
console.log(t)
}
f()
</script>
Gitee — 基于 Git 的代码托管和研发协作平台
2.导航案例用 async-await进一步优化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>案例_分类导航</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
a {
text-decoration: none;
color: #333;
}
ul {
list-style: none;
}
.container {
width: 980px;
margin: 0 auto;
}
.top {
display: flex;
width: 100%;
height: 80px;
align-items: center;
justify-content: space-around;
position: relative;
}
.top>li {
text-align: center;
}
.top>li>a {
border-bottom: 1px solid transparent;
}
.top>li:hover>a {
border-color: #27ba9b;
color: #27ba9b;
}
.top>li:hover>.sub {
opacity: 1;
transform: scale(1, 1);
}
.sub {
position: absolute;
left: 0;
top: 80px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
width: 100%;
display: flex;
align-items: center;
height: 100px;
opacity: 0;
transform: scale(1, 0);
transform-origin: top center;
transition: all 0.3s .1s;
}
.sub li {
width: 120px;
text-align: center;
}
.sub li a {
display: block;
font-size: 14px;
padding-top: 8px;
}
.sub li a span {
display: block;
}
.sub li a img {
width: 60px;
height: 60px;
vertical-align: middle;
}
</style>
</head>
<body>
<div class="container">
<ul class="top" id="top">
<li>
<a href="javascript:;">首页</a>
<ul class="sub">
<li>
<a href="javascript:;">
<span>砂锅厨具</span>
<img src="https://yanxuan.nosdn.127.net/3102b963e7a3c74b9d2ae90e4380da65.png?quality=95&imageView" alt="">
</a>
</li>
</ul>
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios@0.27.2/dist/axios.min.js"></script>
<script>
// 基地址
axios.defaults.baseURL = 'http://ajax-api.itheima.net'
// 拼接ul>li字符串
function buildStr(res) {
const str = res.map(item => {
const obj = item.data.data
console.log(obj)
const lis = obj.children.map(o =>{
return `<li>
<a>
<span>${o.name}</span>
<img src="${o.picture}"/>
</a>
</li>`
}).join('')
return `<li>
<a href="">${obj.name}</a>
<ul class="sub">
${lis}
</ul>
</li>`
}).join('')
return str
}
async function getMenu() {
// 1. 拿到一级菜单
const res = await axios.get('/api/category/top')
const topMenus = res.data.data
// 2. 拿所有的二级菜单
// 2.1 创建一个promse数组:每一个元素都是一个ajax请求
const ajaxPromise = topMenus.map(it => axios.get('/api/category/sub?id='+it.id))
// Promise.all([promise1, promise2....])
// 2.2 调用promise.all
const r = await Promise.all(ajaxPromise) // ===> promise对象;状态, 值
// console.log(r)
// axios.get('/api/category/sub/'+topMenus[0].id)
return r
}
async function createMenu(){
try {
// 获取菜单信息
const res = await getMenu()
// 拼接ul>li字符串
const str = buildStr(res)
console.log(str)
// 设置字符串
document.querySelector('#top').innerHTML = str
} catch(err){
console.log(err)
}
}
createMenu()
</script>
</body>
</html>
3.理解异步代码执行-微任务和宏任务
<script>
console.log(1)
console.log(Date.now(), '.....')
setTimeout(() => {
console.log(2)
console.log(Date.now(), '.....')
}, 1000)
const t = Date.now()
while(Date.now() - t < 2000){
}
</script>
4.微任务宏任务案例1
<script>
console.log(1)
setTimeout(function() {
console.log(2)
new Promise(function(resolve) {
console.log(3)
resolve()
}).then(function() {
console.log(4)
})
})
new Promise(function(resolve) {
console.log(5)
resolve()
}).then(function() {
console.log(6)
})
setTimeout(function() {
console.log(7)
new Promise(function(resolve) {
console.log(8)
resolve()
}).then(function() {
console.log(9)
})
})
console.log(10)
</script>
<!-- <script>
console.log(1);
setTimeout(() => {
console.log(2);
}, 0)
let p = new Promise((resolve, reject) => {
resolve(3)
})
p.then(res => {
console.log(res);
})
console.log(4);
</script> -->
5.微任务和宏任务案例2
<script>
setTimeout(() => { console.log(1)}, 0)
new Promise((resolve, reject) => {
console.log(2)
// resolve('p1')
new Promise((resolve, reject) => {
console.log(3)
setTimeout(() => {
resolve('setTimeout2')
console.log(4)
}, 0)
// resolve('p2')
}).then(data => {
console.log(data)
})
setTimeout(() => {
resolve('setTimeout1')
console.log(5)
}, 0)
}).then(data => {
console.log(data)
})
console.log(6)
</script>
<!-- <script>
new Promise((resolve, reject) => {
resolve(1)
new Promise((resolve, reject) => {
resolve(2)
}).then(data => {
console.log(data)
})
}).then(data => {
console.log(data)
})
console.log(3)
</script> -->
<!-- <script>
console.log(1)
setTimeout(function() {
console.log(2)
}, 0)
const p = new Promise((resolve, reject) => {
console.log(3)
resolve(1000) // 标记为成功
console.log(4)
})
p.then(data => {
console.log(data)
})
console.log(5)
</script> -->
<!-- <script>
console.log(1);
setTimeout(() => {
console.log(2);
}, 0)
console.log(3);
</script>
<script>
console.log(4);
setTimeout(() => {
console.log(5);
}, 0)
console.log(6);
</script> -->
6.微任务和宏任务-async-await的案例
<script>
async function async1 () {
console.log('1');
await async2();
console.log('2');
}
async function async2 () {
console.log('3');
}
console.log('4');
setTimeout(function () {
console.log('5');
}, 0);
async1();
new Promise(function (resolve) {
console.log('6');
resolve();
}).then(function () {
console.log('7');
});
console.log('8');
</script>
<!--
<script>
console.log(1);
// --------------
// await 函数()
// 其他代码
// -------------
// 执行这个函数,跳出这个aysnc,把其他代码,加到微任务
async function fnOne() {
console.log(2);
await fnTwo();
console.log(3);
}
async function fnTwo() {
console.log(4);
}
fnOne();
setTimeout(() => { console.log(5); }, 2000);
let p = new Promise((resolve, reject) => { // new Promise()里的函数体会马上执行所有代码
console.log(6);
resolve();
console.log(7);
})
setTimeout(() => {
console.log(8)
}, 0)
p.then(() => {
console.log(9);
})
console.log(10);
</script>
<script>
console.log(11);
setTimeout(() => {
console.log(12);
let p = new Promise((resolve) => {
resolve(13);
})
p.then(res => {
console.log(res);
})
console.log(15);
}, 0)
console.log(14);
</script> -->
7.个人信息修改案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>08.案例_个人信息修改</title>
<link rel="stylesheet" href="https://unpkg.com/bootstrap@5.1.3/dist/css/bootstrap.min.css" />
<style>
.form-select {
width: 103px;
display: inline-block;
}
.col-form-label {
text-align: right;
}
.figure-img {
width: 100px;
height: 100px;
cursor: pointer;
}
#upload {
display: none;
}
</style>
</head>
<body>
<div class="container">
<h1 class="p-5">个人设置</h1>
<form class="col-6">
<div class="row mb-3">
<label class="col-form-label col-3">昵称:</label>
<div class="col-9">
<input id="nickname" class="form-control col-9" type="text" name="nickname" />
</div>
</div>
<div class="row mb-3">
<label class="col-form-label col-3">籍贯:</label>
<div class="col-9">
<select id="province" class="form-select col-4" name="province">
<option value="">--省--</option>
</select>
<select id="city" class="form-select col-4" name="city">
<option value="">--市--</option>
</select>
<select id="area" class="form-select col-4" name="area">
<option value="">--区--</option>
</select>
</div>
</div>
<div class="row mb-3">
<label class="col-form-label col-3">头像:</label>
<div class="col-9">
<input class="form-control col-9" type="hidden" name="avatar" />
<figure class="figure">
<input type="file" id="upload" />
<img id="avatar" src="https://yanxuan-item.nosdn.127.net/12a882699bd531a1bd428bffe1989525.jpg"
class="figure-img img-fluid rounded" alt="..." />
<figcaption class="figure-caption">修改头像</figcaption>
</figure>
</div>
</div>
<div class="row mb-3">
<label class="col-3"></label>
<div class="col-9">
<button id="btnSave" class="btn btn-primary">保存</button>
</div>
</div>
</form>
</div>
<script src="https://unpkg.com/bootstrap@5.1.3/dist/js/bootstrap.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.27.2/dist/axios.min.js"></script>
<script src="./lib/form-serialize.js"></script>
<script>
// 1. 数据回填:获取数据,显示出来
axios.defaults.baseURL = 'http://ajax-api.itheima.net/'
function $(id) {
return document.querySelector('#' + id)
}
async function getInfo () {
const res = await axios.get('api/settings')
// const obj = res.data.data
const { area, avatar, city, nickname, province} = res.data.data
// console.log(obj);
// 数据回填
$('avatar').src = avatar
$('nickname').value = nickname
// 把省的数据整体填入select
const resProvince = await axios.get('/api/province')
// console.log(resProvince);
$('province').innerHTML += resProvince.data.data.map(p => `<option value="${p}">${p}</option>`).join('')
$('province').value = province
// 把市的数据整体填入select
const resCity = await axios.get('/api/city?pname='+province)
// console.log(resCity);
$('city').innerHTML += resCity.data.data.map(p => `<option value="${p}">${p}</option>`).join('')
$('city').value = city
// 把区的数据整体填入select
const resArea = await axios.get(`/api/area?pname=${province}&cname=${city}`)
console.log(resArea);
$('area').innerHTML += resArea.data.data.map(p => `<option value="${p}">${p}</option>`).join('')
$('area').value = area
}
getInfo()
// 给省这个下拉框添加change事件
$('province').addEventListener('change',async () => {
// 拿到最新的省
const province = $('province').value
// 发请求,得到对应的市
const resCity = await axios.get('/api/city?pname='+province)
// 添加到页面
$('city').innerHTML = resCity.data.data.map(p => `<option value="${p}">${p}</option>`).join('')
// 默认选中第一个市
const city = resCity.data.data[0]
$('city').value = city
// 根据最新的city,去请求得到对应的区
// 把区的数据整体填入select
const resArea = await axios.get(`/api/area?pname=${province}&cname=${city}`)
console.log(resArea);
$('area').innerHTML = resArea.data.data.map(p => `<option value="${p}">${p}</option>`).join('')
$('area').value = resArea.data.data[0]
})
// 给市这个下拉框添加change事件
$('city').addEventListener('change',async () => {
// 拿到最新的省
const province = $('province').value
// 拿到最新的市
const city = $('city').value
// 发请求,得到对应的市
// console.log(city)
// 根据最新的city,去请求得到对应的区
// 把区的数据整体填入select
const resArea = await axios.get(`/api/area?pname=${province}&cname=${city}`)
console.log(resArea);
$('area').innerHTML = resArea.data.data.map(p => `<option value="${p}">${p}</option>`).join('')
$('area').value = resArea.data.data[0]
})
// 保存
$('btnSave').addEventListener('click', async (e) => {
e.preventDefault()
console.log(1)
const nickname = $('nickname').value
const province = $('province').value
const city = $('city').value
const area = $('area').value
const avatar = $('avatar').src
try {
await axios.put('/api/settings1', {
nickname,
province,
city,
area,
avatar
})
alert('ok')
} catch(err){
alert('error')
}
})
</script>
</body>
</html>