JS中同步、宏任务、微任务、页面渲染顺序和时机
刚进入程序的整个代码块属于一个宏任务,然后开始依次执行宏任务中的同步代码、同步代码执行完毕后,如果存在微任务代码的话,则执行完所有的微任务代码。微任务都执行完毕后,此时进入到页面渲染阶段,如果存在 重排(Layout) 和 重绘(Paint) 的话,则会进行页面渲染。倘若存在
requestAnimationFrame(rAF)回调的话,则会在渲染前执行。之后开始继续轮询下一个宏任务,以上述相同的顺序进行执行。
易混淆
鼠标、键盘等事件监听的注册是属于同步的,但其回调函数的执行属于异步的宏任务。
实例加深理解
console.log('1');
setTimeout(function () {
console.log('2');
setTimeout(function(){
console.log('testTimeout')
},0)
new Promise(function(resolve, reject) {
console.log('promise-start2');
resolve();
}).then(function() {
console.log('promise-end2');
});
},0);
new Promise(function(resolve, reject) {
console.log('promise-start');
resolve();
}).then(function() {
console.log('promise-end');
});
setTimeout(function () {
console.log('3');
},0);
console.log('4');
执行输出结果为:
1
promise-start
4
promise-end
2
promise-start2
promise-end2
3
testTimeout
通过这个实例可知,即使遇到宏任务中还嵌套着宏任务,那么嵌套的宏任务就被推入到宏任务队列尾部等待执行,即排在已有任务的后面。