宏任务与微任务的任务队列以及渲染时机
概要阐述
了解了同步和异步任务(宏任务和微任务)之后,我对DOM的渲染先后顺序有了一定的了解。
宏任务和微任务的任务队列
首先需要了解的是,一次执行,是将执行队列的任务依次执行。
任务的执行是从宏任务开始
在执行的过程中,将遇到的宏任务和微任务分别放进对于的任务队列。
在执行下一个宏任务之前,先执行所有的微任务。
这个时候,也会是执行下一个宏任务之前,执行完所有微任务之后,会进行DOM渲染。
下面举个例子:
setTimeout(() => {
console.log(1);
new Promise(resolve => {
console.log(3);
})
setTimeout(() => {
console.log(4);
},0)
},0)
setTimeout(() => {
console.log(2);
},0)
输出结果是
1324
从上至下,所有的setTimeout 标记为 a,b,c
1.第一次宏任务,a进入执行队列,过0ms之后将promise和 b放进任务队列 ,之后c进入执行队列,过0ms后,将 () => { console.log(2);}放入任务队列,第一个宏任务结束
执行队列 | 宏任务队列 | 微任务队列 |
---|---|---|
a | console.log(1); new Promise(resolve => {console.log(3) ;}) setTimeout(() => {console.log(4); },0) | – |
c | () => { console.log(2);} | – |
2.第二个宏任务,将宏任务队列的第一个任务取出,放入任务队列。执行任务队列。打印
1
遇到Promise 执行函数体,打印
3
遇到b 过0ms后将b的回调放入到宏任务队列。
执行前:
执行队列 | 宏任务队列 | 微任务队列 |
---|---|---|
console.log(1); new Promise(resolve => {console.log(3) ;}) setTimeout(() => {console.log(4); },0) | () => { console.log(2);} | – |
执行后:
打印
1 3
执行队列 | 宏任务队列 | 微任务队列 |
---|---|---|
– | () => { console.log(2);} | – |
– | () => {console.log(4); } | – |
根据目前宏任务队列的顺序,最后输出的是:
2 4
所以,最后的输出结果是
1324
以后根据这个过程就可以分析出来执行结果。
渲染时机
DOM的渲染过程是夹杂在执行过程中的。
在上一个宏任务结束,执行完所有的微任务之后,在下一个宏任务执行之前,会进行渲染。