JS单线程和Event Loop
原因——避免DOM渲染冲突
-
浏览器需要渲染DOM
-
JS可以修改DOM结构
-
JS执行的时候,浏览器DOM会暂停
-
两段JS也不能同时执行(都修改DOM就冲突)
-
webworker支持多线程,但是不能访问DOM
setTimeout // 时间到了再执行 ajax // 加载完再执行
异步问题
-
没按照书写方式执行,可读性差
-
callback中不容易模块化
实现异步的方案——Event Loop
-
事件轮询,JS实现异步的具体解决方案
-
同步代码,直接执行
-
异步函数先放在异步队列中
-
待同步函数执行完毕,轮询执行异步队列的函数
宏任务: script、 setTimeout、setInterval、ajax、requrestAnimationFrame
-
宏任务所处的队列就是宏任务队列
-
第一个宏任务队列中只有一个任务:执行主线程的js代码
-
宏任务队列可以有多个
-
当宏任务队列中的任务全部执行完以后会查看是否有微任务队列,如果有,先执行微任务队列中的所有任务。如果没有就查看是否有宏任务队列。
微任务: Promise().then(回调)、process.nextTick(node中)
-
微任务所处的队列就是微任务队列
-
只有一个微任务队列
-
在上一个宏任务队列执行完毕后如果有微任务队列就执行微任务队列中所有任务
总结:JS是单线程,同时只做一件事,原因是为了避免DOM渲染冲突。异步是一种解决方案,具体的实现就是Event Loop。同步代码直接执行,异步代码先放在异步队列中,待同步代码完毕,轮询执行异步队列中函数。
异步任务又可以分为两种,micro-tast(微任务)和macro-tast(宏任务)。
-
初始化状态:执行stack为空。macro-tast(宏任务)队列中只有一个script脚本。
-
script脚本被推入执行stack,同步代码执行,执行过程可以产生新的macro-task和micro-task,并且推入各自的队列中,script脚本执行完成,则会移除任务队列。
-
macro-task移除队列后,接着执行micro-task。
-
执行UI渲染操作,更新界面。
-
继续执行下一个宏任务

浙公网安备 33010602011771号