js事件循环 microtask macrotask

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js事件循环 microtask macrotask相关的知识,希望对你有一定的参考价值。

上篇文章说了一下js中定时器 setTimeout 和 setInterval 的执行原理。这两个计时器都是异步执行的,这部分体现了js的执行过程。

 

js自身执行的模型是事件循环(event loop)。

js在启动时会创建一个循环,每次循环都会去任务队列(task query)里找要进行的任务。当队列里的一个任务执行完毕,该循环会去找下一个任务去执行。js的执行过程就是循环不断地执行。像定时器,用户触发的事件,promise 等异步执行的代码,都会按规定往这个任务队列推。

任务队列不是只有一个,有 microtasks 和 macrotasks 之分。macrotask query 就是 task query,每个 macrotask 里都有一个 microtask。js开始执行时,会先取一个 macrotask,然后取里面的 microtask 去执行。当前的 microtask 执行完毕之后,会取下一个 microtask 直到 microtask 执行完,然后退出改 macrotask,去执行下一个 macrotask,然后就一直循环下去。就相当于有一个 task query,而这个队列中的每一个 task,也相当于一个 task query。

因此我们观察到的现象直观地来说,就是这些异步方法有一个优先级,microtask 要比 macrotask 优先级高,优先级高的会比优先级低的先执行,同优先级的就根据进入队列的时间去执行。

 

macrotasks: setTimeout setInterval setImmediate I/O UI渲染

microtasks: Promise process.nextTick Object.observe MutationObserver

 

看一个例子:

 1 console.log(‘start‘)
 2 
 3 Promise.resolve().then(() => {
 4     console.log(‘promise 1‘)
 5 })
 6 
 7 setTimeout(() => {
 8     console.log(‘setTimeout 1‘)
 9     Promise.resolve().then(() => {
10         console.log(‘promise 2‘)
11         Promise.resolve().then(() => {
12             console.log(‘promise 3‘)
13         }).then(() => {
14             console.log(‘promise 4‘)
15         })
16     }).then(() => {
17         setTimeout(() => {
18             console.log(‘setTimeout 2‘)
19             Promise.resolve().then(() => {
20                 console.log(‘promise 5‘)
21             })
22         }, 0)
23         console.log(‘promise 6‘)
24     })
25     console.log(‘setTimeout 2‘)
26 }, 0)
27 
28 setTimeout(() => {
29     console.log(‘setTimeout 3‘)
30     Promise.resolve().then(() => {
31         console.log(‘promise 7‘)
32     })
33     console.log(‘setTimeout 4‘)
34 }, 0)
35 
36 Promise.resolve().then(() => {
37     console.log(‘promise 8‘)
38 })

 

执行结果为

start
promise 1
promise 8
setTimeout 1
setTimeout 2
promise 2
promise 3
promise 6
promise 4
setTimeout 3
setTimeout 4
promise 7
setTimeout 2
promise 5

以上是关于js事件循环 microtask macrotask的主要内容,如果未能解决你的问题,请参考以下文章

经久不衰的话题:Js的宏任务(marcroTask)和微任务(microTask)

经久不衰的话题:Js的宏任务(marcroTask)和微任务(microTask)

JS MarcoTasks MicroTasks

Node.js 的事件循环机制

js事件循环机制(Event Loop)

深入理解事件循环机制