本文主要是介绍async/await代码执行顺序分析及宏任务和微任务简介,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、async
带async关键字的函数,是声明异步函数,返回值是promise对象,如果async关键字函数返回的不是promise,会自动用Promise.resolve()包装。
返回值为 Promise {<resolved>: "test"}。
二、await
await等待右侧表达式的结果,这个结果是promise对象或者其他值。
如果它等到的不是一个 promise 对象,那 await 表达式的运算结果就是它等到的东西。
如果它等到的是一个 promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。
由于test()造成的阻塞,console.log('end')会等到两秒后执行
所以为了避免造成阻塞,await 必须用在 async 函数中,async 函数调用不会造成阻塞。
先执行console.log('end'),两秒后执行console.log('test')
如果await用在普通函数中,会报错,如下:
三、async/await的执行顺序
遇到await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,继续执行await后面的代码。(好好理解一下上面的说明。也就是说,await只会阻塞当前async方法内的代码,不会影响外部代码的执行)
以下面的代码分析:
执行的结果:
· 首先执行宏任务,执行test1函数,执行console.log('statr test1')
· 遇到await,先执行右边test2中的console.log('test2'),中断了后面的代码,执行test1外面的同步代码
· 执行console.log('start async');
· 遇到setTimeout,推到到下个宏任务队列中
· 执行Promise里面的同步代码console.log('promise1')
· 运行到promise().then,发现是promise对象,推到微任务队列中
· 执行console.log('end async')
· test1外面的同步代码执行结束后,回到test1中,console.log(await test2())执行完成后返回Promise {<resolved>: "return test2 value"},是promise对象,推到微任务队列中
· 此时第一个宏任务结束,执行所有的微任务,因为微任务队列先进先出,所以先执行console.log('promise2'),后执行console.log('return test2 value')
· 执行test2完成后,后面的代码不再阻塞,执行console.log('end test1');
· 执行下个宏任务,即执行console.log('setTimeout');
补充下有关宏任务和微任务的知识
宏任务和微任务都是队列,宏任务有script、setTimeout、setInterval等,微任务有Promise.then catch finally、process.nextTick等,宏任务和微任务的关系如下:
先执行第一个宏任务,执行结束后,执行所有的微任务,然后执行下个宏任务。
四、async/await的优缺点
1. 优点
相对于promise,async/await处理 then 的调用链,代码要清晰很多,几乎和同步代码一样
2. 缺点
滥用 await 可能会导致性能问题,因为 await 会阻塞代码
五、处理reject
1. try/catch
2. catch
参考:
1. https://segmentfault.com/a/1190000007535316
2. https://segmentfault.com/a/1190000017224799
3. https://www.cnblogs.com/wangziye/p/9566454.html
这篇关于async/await代码执行顺序分析及宏任务和微任务简介的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!