事件轮询与DOM渲染顺序

本文深入探讨了JavaScript中事件轮询、DOM渲染、宏任务与微任务的关系。通过对比setTimeout与Promise的执行顺序,揭示了DOM渲染在微任务之后的特性,导致在特定情况下,先设置的颜色可能被后续微任务覆盖,从而影响最终的页面显示效果。理解这一原理对于优化JavaScript代码和提升用户体验至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

事件轮询与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.背景颜色变为绿色
     })

  })

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Raccom

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值