事件轮询与DOM渲染顺序

2023-09-24 6 0

事件轮询与DOM渲染

总结

JS代码执行顺序为:

宏任务(script代码) => 微任务 => DOM渲染 => 异步宏任务

首先看下列代码:

	// 为document对象绑定点击事件document.documentElement.addEventListener(`click`,()=>{// 先将文档背景颜色改为粉色document.documentElement.style.backgroundColor="pink"// 设置定时器setTimeout(()=>{// alert弹窗阻塞线程 便于观察当前页面背景颜色alert(``)// 背景颜色改为绿色document.documentElement.style.backgroundColor="green"})})

代码的执行结果为背景颜色变为粉色,弹出弹窗,点击背景颜色变为绿色

跟我们预期的结果一样

而同样是异步代码,将setTimeout换为Promise后

  document.documentElement.addEventListener(`click`,()=>{document.documentElement.style.backgroundColor="pink"Promise.resolve().then(()=>{alert(``)document.documentElement.style.backgroundColor="green"})})

代码的执行结果为弹窗(背景颜色是白色),点击背景颜色变为绿色

 document.documentElement.style.backgroundColor="pink"  // <----这行代码不生效了???

同样都是先同步后异步为什么会有这种区别呢

原因就是DOM渲染顺序的问题。

click是异步宏任务,点击之后click函数代码事件循环进入执行栈,此时执行click里的宏任务,

DOM渲染的代码虽然是宏任务,但执行后不会马上渲染到页面,它的优先级在微任务之后

然后执行到Promise,把then后的代码添加到微任务队列,

此时微任务队列的优先级高于DOM渲染,所以先执行微任务,

宏任务里的背景颜色(粉色)还没渲染,就被then里面的微任务代码(绿色)覆盖了

实际的执行顺序为

  document.documentElement.addEventListener(`click`,()=>{document.documentElement.style.backgroundColor="pink"//1.背景颜色粉色(未渲染)Promise.resolve().then(()=>{alert(``)  //2.弹窗document.documentElement.style.backgroundColor="green" //3.背景颜色绿色(未渲染,将粉色覆盖)})//4.DOM 渲染 背景颜色})

由上到下执行,所以alert时背景颜色没变,点击确认后,背景绿色,DOM渲染,页面就为绿色

而setTimeout是异步宏任务,是在宏任务,微任务和DOM渲染执行完后才执行

这里因为没有微任务,所以执行顺序就为宏任务 DOM渲染 异步宏任务(定时器)

  document.documentElement.addEventListener(`click`,()=>{document.documentElement.style.backgroundColor="pink"//1.同步代码 执行完后 马上DOM渲染 背景颜色变为粉色setTimeout(()=>{alert(``)  //2.弹窗 document.documentElement.style.backgroundColor="green" //3.背景颜色变为绿色})})

所以弹窗时背景颜色为粉色,点击后变为绿色

代码编程
赞赏

相关文章

LeetCode之Isomorphic Strings
LeetCode之Combination Sum III
LeetCode之Find Minimum in Rotated Sorted Array II
LeetCode之Majority Element II
LeetCode之Product of Array Except Self
LeetCodeConvert Sorted List to Binary Search Tree