js事件循环机制

本来以为小米面的还行,回来一思考发现果然还是底子薄,实在是弱爆了,由此谈js的event loop
先解释三张图:
主线程和任务队列:


浏览器从入口开始解析执行js代码,这个时候整个js代码放到一个macroTask中(此时任务队列只有一个元素,即当前macroTask),在执行的过程中遇到了dom、ajax、Promise等异步操作,会产生新的任务,加入到任务队列的末尾,需要调用运行环境api(node/浏览器)的就会自己去调用,而主进程不受影响,当主进程的代码执行完毕之后,就跑到了任务队列中查看(自然是从队头开始),看看哪一个任务已经可以放到主进程中执行了(异步事件完成,开始执行回调,将其压入运行栈),如果出现了新的异步,则添加到队列末尾,主进程栈空后再从队列头开始检查,将执行完毕的异步压入运行栈。

然而!上述内容大致是对的,可是任务队列并不是那么简单的,除了macro队列还有一种micro队列,前者严格遵循顺序每次取出一个压入栈中,但micro却拥有特权,也就是栈空后其实并不像上述所言直接进入macroTask队列寻找可以压入栈的任务,会首先检查是否有microTask,如果有的话,micro会插队优先执行,而且是有多少执行多少,先尽力清空microTask队列,只要主进程执行过程中产生了新的microTask,新的microTask就会不断地插队,记住两个例子,遇到setTimeout就进入macroTask队列,遇到Promise就塞入microTask队列(注意是then里的会塞入event-loop中去,promise接受的立即执行的函数真的是立即执行的!),队列并没有嵌套,microTask与macroTask始终都只能各自同时存在一个队列,上述图片中两个粉色的microTask并不是同时存在的!