dom到底在js的事件循环哪个阶段,为什么在浏览器用alert验证不准确?

以下代码顺序不一致

setTimeout(() => {alert('暂停点alert');console.log('setTimeout done')}, 0)
document.getElementsByTagName('div')[0].innerHTML = 'FE情报局'
new Promise((resolve) => {resolve()}).then(() => {console.log('promise done')})

按道理应该是微任务->dom渲染->宏任务

但是这里却先出现暂停点alert,浏览器还没出现FE情报局

setTimeout(() => {alert('暂停点alert');console.log('setTimeout done')}, 0)
document.getElementsByTagName('div')[0].innerHTML = 'FE情报局'
new Promise((resolve) => {resolve()}).then(() => {console.log('promise done');alert('promise alert')})

这里先出现promise alert,然后页面显示FE情报局,再出现alert

setTimeout(() => {
  for (let index = 0; index < 1000000; index++) {
    if(index===1000000-1){
      console.log('end')
    }
  }
  console.log('setTimeout done')
},0)
document.getElementsByTagName('div')[0].innerHTML = 'FE情报局'
new Promise((resolve) => {resolve()}).then(() => {
  console.log('promise done')
  for (let index = 0; index < 1000000; index++) {
    if(index===1000000-1){
      console.log('done')
    }
  }
})

这里先出现done,然后FE情报局出现在浏览器中,最后出现end的顺序

自己写了一个文章,但是总觉得是alert的问题,又不知道具体是什么问题

https://segmentfault.com/a/11...

阅读 1.2k
2 个回答

你对事件循环有个误区,事件循环只是实现js异步执行的一种调度机制,浏览器的重绘并不属于 事件循环 的某个阶段,按照 60fps 的刷新率,屏幕是约 16.6ms 刷新一次,也就是说如下更新 dom 的操作:

document.getElementsByTagName('div')[0].innerHTML = 'FE情报局'

你要看到变化需要等每个 16.6ms 帧节点重绘,而 16.6ms 这么长段时间内,可以跑很多轮事件循环了

另外,由于 js 线程和 渲染线程 是互斥的,js 线程执行一些耗时任务时,可能导致 渲染线程 无法在 帧节点 进行重绘,就是我们常说的掉帧了

alert会阻塞浏览器的渲染,为啥不用console.log验证

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏