代码
今天,代码干货,上菜🥬。
先来看这段代码🕶️:
document.body.style.background = 'red';
console.log(1)
Promise.resolve().then(() => {
console.log(2)
document.body.style.background = 'yellow';
})
console.log(3);
浏览器渲染的颜色是什么样子的,打印的结果是什么样子的?停下来,先思考3秒钟。
这结果出来了:输出 1, 3, 2, 黄。
再来看一段代码🕶️:
document.body.style.background = 'red';
console.log(1)
setTimeout(() => {
console.log(2)
document.body.style.background = 'yellow';
})
console.log(3);
同样先思考3秒钟,想出打印应该是什么顺序,以及颜色渲染应该是咋样的。
结果是:1,3,2 页面是先红再黄。
分析
细说:为什么红色没有渲染出来,直接就是黄色了?
document.body.style.background = 'red';
console.log(1)
Promise.resolve().then(() => {
console.log(2)
document.body.style.background = 'yellow';
})
console.log(3);
细说:为什么这段代码就可以先红,后黄?
document.body.style.background = 'red';
console.log(1)
setTimeout(() => {
console.log(2)
document.body.style.background = 'yellow';
})
console.log(3);
俩段代码,一个Promise,一个setTimeout,可以看得出事件循环对浏览器渲染的不同影响:
Promise:
微任务Promise会阻塞渲染,
document.body.style.background = 'red';
Promise.resolve().then(() => {
document.body.style.background = 'yellow';
});
记一个口诀(遇事不决,记口诀):同步任务 -> 微任务 -> 渲染 -> 宏任务。
也就是说,微任务在同步任务后紧接着执行,并且,早于浏览器渲染。
所以也就得出,为什么Promise这段代码不会出现红色闪烁。也就印证了上面的话:等微任务队列执行完后才会进入渲染阶段。
setTimeout:
那对于setTimeout来讲,先看代码:
documnet.body.style.background = 'red';
setTimeout(() => {
document.body.style.background = 'yellow';
})
对于setTimeout来讲,就是说它可以等渲染完成后执行,就是允许中间渲染。
记一个口诀(遇事不决,记口诀):同步任务 -> 微任务 -> 渲染 -> 宏任务。