JS虽然是单线程,但是js是脚本语言,需要在宿主环境里才能运行,然而我们常见的宿主环境浏览器却是多线程的。
GUI线程:负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树
JS引擎线程:也称JS内核,负责处理JS脚本程序,与GUI线程互斥
定时器线程:setInterval与setTimeout所在线程
事件触发线程:将满足触发条件的的事件放入任务队列
异步http请求线程:XHR在连接后是通过浏览器新开一个线程请求
JS引擎线程为主线程,其他的为辅助线程。
宏任务
script
setTimeout/setIterval
setImmediate
I/O
UI rendering
微任务
Promise
Object.observe
MutationObserver
postMessage
浏览器的事件流
1>执行全局script同步代码,形成一个执行栈
2>在执行代码时当遇到异步任务便会将宏任务回调加入宏任务队列,微任务回调加入微任务队列
3>回调放入任务队列也不是立即执行会等待执行栈中的同步任务执行完清空了栈后引擎才能回去任务队列检查是否有任务,如果有便会将任务加入执行栈,然后执行
4>执行栈清空后会去检查微任务队列是否有任务,逐一将其任务加入执行栈中执行,期间再产生微任务则追加到微任务队列末端依次执行直到微任务队列清空,执行栈也清空后,去检查宏任务队列是否有任务,然后按序加入执行栈执行,要注意的是在执行完一次宏任务必须检查微任务队列是否有新的微任务产生,若有则执行,若没有则继续执行宏任务队列中的任务,重复此操作
5>引擎会循环执行上述步骤