前提:在学习 async、await 之前,需要提前了解 js 中的 同步异步任务、promise 等相关知识,可以参考之前的文章:点击查看
文章目录
一、async、await 语法糖的基本认识二、根据案例理解 async、await三、promise、async、await综合案例
一、async、await 语法糖的基本认识
① async(异步):放在 function 前修饰
async 的作用:声明一个 function(也就是一个函数)是异步的。
在函数内 return
,不管 return
的是什么,外部调用这个函数时,获取到的都是一个 Promise
对象(也就是说会对返回结果进行封装),需要通过 函数名().then
获取到 return
值
也就是说:async 修饰的函数,只要有返回,就会返回一个 Promise 对象,如果在函数中 return 一个直接量,async 也会把这个直接量通过 Promise.resolve()
的方式封装成 Promise 对象。
② await(异步–等待):函数内有 await,必须要使用 async 修饰;有 aysnc 修饰的函数,函数内不一定非要有 await 代码;
await 的作用:等待一个异步方法执行完成。如果最终等待的值是成功的 Promise 对象,则会阻塞后面的代码(也就是:将 async 函数剩余任务推入到微任务队列);反之,不会;await 会简化 then,直接得到 resolve 里面的数据二、根据案例理解 async、await
① await + promise对象
function test() { return new Promise(((resolve, reject) => { //假装是你的异步任务: const isSuccess = true if (isSuccess) resolve('任务2成功') else reject('任务2失败') }))}async function main() { //任务1,3,4是同步任务 console.log('任务1') const data = await test(); console.log(data) console.log('任务3')}main()console.log("任务4")
分析:
首先调用 main 函数,由于任务1,3,4是同步任务,本应该先执行,但是定义任务2 的 test 函数返回成功的 promise 对象,所以 await 处,就会将 async 函数剩余任务推入到微任务队列,所以先输出任务4,同步任务执行完之后,最后输出微任务队列中的内容。(并且 await 是直接拿到 resolve 中的值)
假如返回失败的 promise 对象,则 剩余任务不会被推入微任务队列执行,它会返回 Promise.reject(err)
② await + 普通的值
async function main() { console.log('任务1') const data = await 2; console.log(data) console.log('任务3')}main()console.log("任务4")
分析:它本质上是将其转化为 Promise.resolve(2)
,所以会返回一个成功的 promise 对象,也会将 async 函数剩余内容推入到微任务队列中等待执行。
③ await + 函数
function test1(){ console.log("函数1")}async function main() { //任务1,3,4是同步任务 console.log('任务1') await test1() console.log('任务3')}main()console.log("任务4")
分析:如果 await 右边是一个函数(不管这个函数有没有 async 修饰),它都会立刻执行这个函数,而且只有当这个函数执行结束后(即函数完成),才会将 async 剩余任务推入微任务队列。
三、promise、async、await综合案例
1、综合案例一:
async function async1() { console.log(1) await async2() console.log(2)}const async2 = async () => { await (async () => { await (() => { console.log(3) })() console.log(4) })()}const async3 = async () => { Promise.resolve().then(() => { console.log(6) })}async1()console.log(7)async3()
分析代码前,需要:
1、先学习 js 中的立即执行函数 ----> 语法:(函数内容)()
其中()
就是代表立即执行的意思,表示这个函数立即执行,因为函数定义完之后,假如不调,是不会运行的,所以可以使用这个来立即执行函数,比如:
2、再学习 js 中的宏任务队列、微任务队列:异步任务分为微任务、宏任务,微任务优先级>宏任务。常见的微任务有:Promise.then.catch。常见的宏任务有:setTimeout()、setInterval()
再来分析代码:
首先调用async1输出1,遇到await async2()函数,开始立即执行async2()函数,直到async2()函数完成,才将cl(2)推入微任务队列
执行async2时,遇到第一个await,开始执行第一个await后面的函数(先将这个函数定义为A)(因为有 ()
所以可以立即执行),函数A包括两部分:另一个函数、cl(4)。所以接着执行函数A中的内容,遇到第二个await,而且后面又跟着另一个函数(定义为B)(且也是立即执行),所以执行函数B,输出3。函数B执行完,于是将cl(4)推入微服务队列,由于cl(4)没执行,所以函数A也就没执行完,即async2函数没执行完。
至此,微任务队列有:cl(4)
开始执行输出cl(7)
执行async3()函数,将cl(6)推入微任务队列。
至此,微任务队列有:cl(4)、cl(6)
同步任务完成,调用微任务队列任务,输出4,函数A执行完,也就是async2函数执行完,于是将cl2推入微任务队列
至此,微任务队列有:cl(6)、cl(2)
然后接着执行微任务队列:输出6、2
至此,关于 promise、async、await 讲解完毕!有啥问题欢迎评论,后续更新更精彩的文章!!!