取代then函数, 来提取Promise的值
Promise链式调用
// 目标: 使用Promise的链式调用解决问题
// 前提: axios函数在原地返回的就是一个Promise对象
let pname = ''
axios.get('http://ajax-api.itheima.net/api/province').then(res => {
// 2. 获取某个省, 对应的城市列表
pname = res.data.data[5];
return axios.get(`http://ajax-api.itheima.net/api/city?pname=${pname}`)
}).then(res => {
// 3. 获取某个市, 对应的地区列表
let cname = res.data.data[0]
return axios.get(`http://ajax-api.itheima.net/api/area?pname=${pname}&cname=${cname}`)
}).then(res => {
console.log(res);
})
async await语法
async function 函数名() {
const result = await Promise对象
// 拿到Promise对象内成功的结果继续向下执行
}
示例
// 目标: 掌握下async和await语法
// 目的: 用await取代then函数, 来提取成功的值在原地
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('成功的值')
}, 2000)
})
// 普通函数: async+await
async function fn() {
const result = await p
console.log(result)
}
fn()
// 箭头函数: async+await
const myFn = async () => {
const result = await p
console.log(result)
}
myFn()
注意事项
-
await 必须用在async修饰的函数内
-
async修饰后, 此函数为异步函数
-
await之后一般跟promise
-
await不能捕获失败结果, 需要使用try+catch关键字捕获
-
/* try和catch语法 try { // 这里放可能在执行中报错的代码 // 如果报错会终止代码继续执行, 直接跳转进catch里执行 } catch (err) { // err接收try大括号内报错抛出的异常代码 } */ let p = new Promise((resolve, reject) => { setTimeout(() => { // resolve(1) reject(new Error('失败')) }, 2000) }) async function myFn() { try { const res = await p console.log(res); } catch (err) { console.error(err) } } myFn()
使用async await优化回调地狱
// 目标: 使用Promise的链式调用解决问题
// 前提: axios函数在原地返回的就是一个Promise对象
async function f() {
const provinces = await axios.get('http://ajax-api.itheima.net/api/province')
const pname = provinces.data.data[5]
const citys = await axios.get(`http://ajax-api.itheima.net/api/city?pname=${pname}`)
const cname = citys.data.data[0]
const areas = await axios.get(`http://ajax-api.itheima.net/api/area?pname=${pname}&cname=${cname}`)
return areas
}
f()
EventLoop事件循环
JavaScript 是一门单线程执行的脚本语言。也就是说,同一时间只能做一件事情。
javaScript要运行在宿主环境中(浏览器,nodejs)下。浏览器内部有执行js代码的引擎(V8引擎)
排队是任务是以事件及其回调的方式存在的。
当事件(用户的点击,图片的成功加载)发生时,将其回调添加到任务队列;主线程上的任务完成之后,就会从任务队列中取出任务来执行,
话术
浏览器中的EventLoop(这个比较偏理论一点,我是这样理解的):js是单线程的,一次只能做一件事。js在浏览器这个宿主环境中运行。浏览器是多线程的,用户交互,定时器,网络请求等等浏览器中的事件会产生对应的任务,任务多了要在任务队列中排队,浏览器的主线程依次取出任务来执行,此过程不断重复从而形成一个循环,称为eventLoop。
概念_微任务和宏任务
异步任务
不是马上执行,是放入到队列中等待;
如果所有的任务都要按序等待,那么也不行,需要有一个能插队的机制。所以又将异步任务分为微任务和宏任务,同时对应微任务队列和宏任务队列。
当主线程空闲时,先执行微任务队列中的任务,再去执行宏任务队列中的任务。
微任务队列和宏任务队列
微任务代码(js语法)
-
Promise对象.then()
(.then( )里面的是微任务)
宏任务代码(宿主环境)
-
script
-
dom事件
-
ajax
-
setTimout

经典面试题
<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>
<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>
4 1 3 6 8 2 7 5
<script>
console.log(1);
async function fnOne() {
console.log(2);
await fnTwo(); // 右结合先执行右侧的代码, 然后等待
console.log(3);
//await等于promis
// new Promise((resolve,reject)=>{
// 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>
6 7 10 3 9 11 14 8 12 15 13 5
本文介绍了async/await的使用,强调了其在优化Promise链式调用中的作用,以及注意事项,如await必须在async函数内使用。接着探讨了JavaScript的EventLoop事件循环机制,包括微任务和宏任务的概念,解释了为何需要微任务队列和宏任务队列,以及它们如何影响异步执行的顺序。最后,列举了一些相关的面试题目。
1102

被折叠的 条评论
为什么被折叠?



