事件循环,事件执行顺序和渲染

问题描述 投票:0回答:1

enter image description here

为什么此代码在执行微任务后不会触发渲染?enter image description here

为什么在计时器之前执行后消息?

javascript html event-loop
1个回答
0
投票

为什么此代码在执行微任务后不会触发渲染?

它会,否则您将看不到正在更新的文本...

也许您无法从开发工具中分辨出来?

这是可能,因为现在通常将鼠标事件限制在屏幕刷新率,这意味着,当分派鼠标事件的任务将运行时,您已经在绘画框中,这可能是为了其他原因(据我所知,mousemove事件是通过这种方式限制的,而不是click ...)。因此,在执行Promise callback will get executed步骤之前,您的update the rendering是同步的(只有第六步“将currentTask设置为null”),然后所有的开发工具都将看到一个正常的绘制框架,就像以前一样期待。因此maybe,开发工具在这里不会显示任何特殊之处,但是鉴于您的主张范围很广,很难指出一个特定的原因,这只是我的理论。

您可以尝试通过从此类事件内部调用requestAnimationFrame来验证该理论,并检查它是否在同一事件循环迭代中执行:

onclick = (evt) => {
  console.clear();
  setTimeout( () => console.log( 'timeout' ), 0 );
  requestAnimationFrame( () => console.log( 'rAF' ) );
};
Click anywhere<br>
If "rAF" gets logged before "timeout", the click event got handled in a painting frame.

对我来说,它经常在Chrome中运行,而在Firefox中仅偶尔运行一次,但是与此同时,我知道Chrome's rAF is broken ...因此,这一理论非常薄弱。


为什么在计时器之前执行后消息?

这取决于User-Agent(浏览器)以及何时执行此代码以使该语句为true,当然还取决于这样做的原因。

[In Chrome,他们将传递给setTimeout的超时值设置为最少1ms:

  base::TimeDelta interval_milliseconds =
    std::max(base::TimeDelta::FromMilliseconds(1), interval);

<< [message任务没有超时,因此将立即排队。因此,如果没有其他任务要处理,那么它将是下一个执行的任务,距离1ms超时还没有解决。

[In Firefox,他们将由setTimeout安排的任务视为低优先级,

从页面加载安排时的任务”(这意味着在Firefox中,消息任务实际上会在setTimeout以后触发)是在页面加载后安排的:

function test() { setTimeout(function setTimeout1() { console.log('setTimeout1') }, 0) var channel = new MessageChannel(); channel.port1.onmessage = function onmessage1() { console.log('postMessage'); Promise.resolve().then(function promise1() { console.log('promise1'); }) }; channel.port2.postMessage(0); setTimeout(function setTimeout2() { console.log('setTimeout2') }, 0); console.log('sync'); } console.log( 'testing @ page load' ); test(); setTimeout(() => { console.log( 'testing after page load' ); test(); }, 1000 ); /* results in Firefox: testing @ page load sync postMessage promise1 setTimeout1 setTimeout2 testing after page load sync setTimeout1 setTimeout2 postMessage promise1 */
)。因此,在这种特殊的页面加载情况下,他们将消息任务比超时任务更为重要,并且当任务执行者必须选择下一步执行哪个任务时(作为first step of the Event Loop processing model的一部分),它将在超时时间内选择消息。
但是这些是实现上的怪癖,规范中没有任何东西可以使这种行为形式化。    
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.