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 })
执行结果为
以上是关于js事件循环 microtask macrotask的主要内容,如果未能解决你的问题,请参考以下文章
经久不衰的话题:Js的宏任务(marcroTask)和微任务(microTask)