主要内容:
event loop(事件循环/事件轮询)机制、promise、async/await 和 宏任务/微任务。
1、请描述event loop (事件循环/事件轮询)机制
js是单线程的,异步要基于回调来实现,event loop(事件循环/事件轮询)就是异步回调的实现原理。
首先我们需要明白js是如何执行的:从前到后,一行一行执行,如果某一行执行报错了,则停止下面代码的执行,先将同步代码执行完毕,再执行异步代码。
![998c608ec0a705610186a639dc94a3c4.png](https://i-blog.csdnimg.cn/blog_migrate/c8387252f872d82dad20422145ed3222.png)
根据上图所示,event loop的执行原理如下:
(1)同步代码,一行一行执行,是放在call stack(调用堆栈)中执行的
(2)遇到异步代码,先记录下在web API中,等待时机(定时、网络请求等)
(3)时机到了,就移动到callback queue(回调队列)中
(4)如果 call stack 为空(即同步代码执行完毕) event loop 开始工作
(5)轮询查找 callback queue, 如有则移动到call stack执行
(6)然后继续轮询查找,直到完成
2、DOM事件 和 event loop
js是单线程的
异步(setTimeout、ajax等)使用回调,是基于event loop的
DOM事件也使用回调,也基于event loop
3、promise
promise有三种状态:pending、resolved、rejected
pending->resolved、pending->rejected 变化是不可逆的
状态的表现:
pending状态, 不会触发 then 和 catch
resolved状态, 会触发后续的 then 回调函数
rejected状态, 会触发后续的 catch 回调函数
then 和 catch 改变状态
then 正常返回 resolved, 里面有报错则返回 rejected
catch 正常返回 resolved, 里面有报错则返回 rejected
4、什么是宏任务(macroTask)?什么是微任务(microTask)?
宏任务: setTimeout、setInterval、ajax、DOM事件
微任务: promise 、async/await
微任务执行时机要比宏任务早
宏任务和微任务的区别?
宏任务: DOM渲染后触发, 如setTimeout
微任务: DOM渲染前触发, 如promise
从event loop解释,为何微任务执行更早: 微任务是es6语法规定,而宏任务是由浏览器规定
5、event loop 和 DOM渲染
js是单线程的,而且和DOM渲染共用一个线程
js执行的时候,得留一些时机供DOM渲染
执行流程:
(1)call stack 空闲
(2)尝试 DOM 渲染
(3)触发 event loop
(4)每次call stack 清空(即每次轮询结束),即同步任务执行完
(5)都是DOM重新渲染的机会,DOM结构如有改变则重新渲染
(6)然后再去触发下一次 event loop
6、async/await
async/await 是同步语法,解决异步回调 callback hell 问题,promise then catch 链式调用,但也是基于回调函数的。
async/await 和 promise的关系: async/await 是解决异步回调的,但和promise并不互斥,两者相辅相成。
执行async函数,返回的是promise对象
await 相当于 promise的then
try...catch 可捕获异常,代替了promise的catch