简洁明了探索浏览器Event loop

前段时间我对于浏览器Event loop中的MacroTask和MicroTask哪一个先执行有所困惑,苦于搜索也没有发现很明确的答案,因而决定深刻探索浏览器Event loop,现有所愚见,想与你们分享,但愿能帮助到那些还在爬坑的人。
1.什么是Event loop?segmentfault

developer.mozilla.org给出的解释是这样的:promise

一个 JavaScript 运行时包含了一个待处理的消息队列。每个消息都关联着一个用以处理这个消息的函数。

在事件循环期间的某个时刻,运行时从最早进入队列的消息开始处理队列中的消息。浏览器

大体能够理解为Event loop用来处理JavaScript事件执行的前后顺序。浏览器端Event loop中的异步队列有两种:MacroTask队列和 MicroTask队列。它们分别包括:

2.关于MacroTask和MicroTask。异步

MicroTask: process.nextTick ,promise ,MutationObserver,其中 process.nextTick 为 Node 独有。
MacroTask: script(总体代码),setTimeout ,setInterval ,setImmediate ,I/O ,UI rendering。

浏览器会不断从task队列中按顺序取task执行。
大致状况以下:
clipboard.png函数

每执行完一个Macrotask都会检查microtask队列是否为空,若是不为空则会一次性执行完全部microtask。oop

3.同步事件和异步事件怎么处理?post

clipboard.png

一开始执行栈空,micro 队列空,macro 队列里有且只有一个 script 脚本(总体代码)。而后全局上下文(script 标签)被推入执行栈,同步代码执行。在执行的过程当中,会判断是同步任务仍是异步任务,经过对一些接口的调用,能够产生新的 macro-task 与 micro-task,它们会分别被推入各自的任务队列里。同步代码执行完了,script 脚本会被移出 macro 队列,这个过程本质上是队列的 macro-task 的执行和出队的过程。须要注意的是:当 macro-task 出队时,任务是一个一个执行的;而 micro-task 出队时,任务是一队一队执行的。所以,咱们处理 micro 队列这一步,会逐个执行队列中的任务并把它出队,直到队列被清空。spa

也就是说循环是这样一个过程:
先执行宏任务,而后查看是否有微任务队列。若是有,先执行微任务队列中的全部任务,若是没有,会读取宏任务队列中排在最前的任务,执行宏任务的过程当中,遇到微任务,依次加入微任务队列。栈空后,再次读取微任务队列里的任务。code

4:总结
一句话:server

对于浏览器Event loop来讲,因为script(总体代码)先执行,因此说MacroTask先于MicroTask执行。

参考文章:

浏览器与Node的事件循环(Event Loop)有何区别?
一篇文章教会你Event loop
什么是浏览器的事件循环

相关文章
相关标签/搜索