Javascript innerHTML是异步的吗?

Javascript innerHTML是异步的吗?,javascript,html,google-chrome,dom,Javascript,Html,Google Chrome,Dom,我希望我不会愚弄自己,但我正在努力理解这两行代码中发生了什么: document.body.innerHTML = 'something'; alert('something else'); 我观察到的是,警报显示在HTML更新之前(或者可能已经更新,但页面尚未刷新/重新绘制/其他任何内容) 看看这是什么意思 请注意,即使将alert放入setTimeout(…,0)中也无济于事。看起来innerHTML实际更新页面需要更多的事件循环 编辑: 我忘了提到我正在使用Chrome,也没有检查其他浏

我希望我不会愚弄自己,但我正在努力理解这两行代码中发生了什么:

document.body.innerHTML = 'something';
alert('something else');
我观察到的是,警报显示在HTML更新之前(或者可能已经更新,但页面尚未刷新/重新绘制/其他任何内容)

看看这是什么意思

请注意,即使将
alert
放入
setTimeout(…,0)
中也无济于事。看起来
innerHTML
实际更新页面需要更多的事件循环

编辑:


我忘了提到我正在使用Chrome,也没有检查其他浏览器。看起来它只在Chrome中可见。尽管如此,我仍然对发生这种情况的原因感兴趣。

是的,它是同步的,因为这是有效的(继续,在控制台中键入它):


在看到页面更改之前看到警报的原因是浏览器呈现需要更多的时间,并且没有javascript逐行执行的速度快。

innerHTML属性actual会同步更新,但此更改导致的视觉重画是异步进行的

DOM的可视化呈现在Chrome中是异步的,只有在清除当前JavaScript函数堆栈并且浏览器可以自由接受新事件后才会发生。其他浏览器可能使用单独的线程来处理JavaScript代码和浏览器呈现,或者在警报停止执行另一个事件时,它们可能会让某些事件获得优先级

您可以从两个方面看到这一点:


  • 如果您为(var i=0;i添加
    for,设置innerHTML是同步的,您可以对DOM进行的大多数更改也是同步的。但是,呈现网页是另一回事

    (记住,DOM代表“文档对象模型”。它只是一个“模型”,一种数据表示。用户在屏幕上看到的是该模型的外观图片。因此,更改模型不会立即更改图片-更新需要一些时间。)

    运行JavaScript和呈现网页实际上是分开进行的。简单地说,首先运行页面上的所有JavaScript(从事件循环-查看更多详细信息),然后浏览器呈现对网页的任何更改以供用户查看。这就是“阻止”的原因运行计算密集型代码会阻止浏览器通过“运行JS”步骤进入“渲染页面”步骤,从而导致页面冻结或结巴

    Chrome的管道如下所示:

    如您所见,所有的JavaScript首先发生。然后页面被样式化、布局、绘制和合成——“呈现”。并不是所有的管道都会执行每一帧。这取决于更改了哪些页面元素(如果有),以及它们需要如何重新呈现

    注意:
    alert()
    也是同步的,并在JavaScript步骤中执行,这就是为什么在看到网页更改之前会出现alert对话框的原因

    现在,您可能会问“等等,在管道中的‘JavaScript’步骤中到底运行了什么?我的所有代码是否每秒运行60次?”答案是“否”,它返回到JS事件循环的工作方式。JS代码只有在堆栈中运行时才运行—从事件侦听器、超时等方面。请参阅(真的)


    这是Chrome的典型特征。@trincot谢谢!我忘了提到我正在使用Chrome,在询问之前没有尝试其他浏览器。你有任何参考资料吗?更改DOM是同步的。渲染DOM实际上是在清除JavaScript堆栈后进行的。JavaScript>样式>布局>绘制>合成。(至少对于Chrome来说是这样。其他浏览器也类似。)只是猜测:警报被阻止会阻止浏览器进入重新绘制步骤,因此,虽然DOM已更改,但它尚未被允许重新绘制;再次,只是猜测。@qbolec检查此视频:谢谢,我确实检查了。但这必须是Chrome特有的功能-它在其他浏览器中按预期工作。或者,可能是他们的缺陷造成的等待页面重新绘制以移动到下一行javascript?警报是否显示正确的文本?(
    文本
    在我的示例中)这将回答您的问题,即它是否同步。浏览器呈现与javascript执行是apple and oranges:)它会,但与您提出的问题无关“innerHTML是异步的吗?"。如果该值可以在同步后立即使用,否?我想你的意思是询问更多关于页面呈现的问题,而不是innerHTML的同步质量。是的,问题显然是错误的,但我不知道该问什么。如果我知道正确的值,我可能会找到答案。我不是故意要问,谢谢你的回答太好了!谢谢你的回答!请不要这样,甚至
    setTimeout(func,1)
    每次都不起作用,请查看此视频:谢谢您的回答。我确实知道有关事件循环等的一些详细信息。此管道非常合理,但示例表明,它在每个浏览器中都不相同。如果其他浏览器在显示警报之前等待页面重新绘制,这意味着在单击按钮之间可能会有巨大的延迟n并显示警报本身。我稍后会尝试使用它。@其他浏览器也可以简单地异步重新绘制页面,同时停止javascript内容,直到用户处理警报窗口。这并不意味着他们必须等待重新绘制发生。
    document.body.innerHTML = 'text';
    alert(document.body.innerHTML);// you will see a 'text' alert