gpt4 book ai didi

javascript - 任何证明在渲染之前执行微任务的示例?

转载 作者:行者123 更新时间:2023-12-04 14:13:23 25 4
gpt4 key购买 nike

我看到好几篇文章都说渲染步骤在微任务之后。
我用这个代码测试它:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<p>test</p>
<script>
const p = document.querySelector('p');
p.textContent = 'text';
Promise.resolve().then(function microtask() {
debugger;
p.textContent = 'Promise';
});
</script>
</body>
</html>
这段代码似乎显示 UI 是 在微任务运行之前重新渲染 .
我想错了吗?有没有很好的例子表明渲染是在微任务运行之后?

最佳答案

您可以通过查看 event-loop processing model 来简单地证明这一点。 .在省略我们不感兴趣的几个步骤的同时解释其当前状态:


  • 选择要执行的任务


  • 执行该任务


  • 执行微任务端点


  • 更新渲染(如果需要的话)


  • 重复


  • 所以在这里很明显微任务在渲染发生之前被执行。
    还不相信?
    这是一个片段,其中 将阻止您的用户界面 5 秒 仅使用微任务。在这个锁被释放之前,页面内容不会被渲染:

    // We wrap our code in a 0 timeout and two rAF levels
    // to be sure the initial rendering of the page did occur
    setTimeout( () => {
    requestAnimationFrame( () => {
    requestAnimationFrame( () => {

    // Now we modify the DOM
    document.querySelector( 'p' ).textContent = "modified";
    // and we start locking the UI using a Promise chain
    const start = performance.now();
    (function lockUI() { // IIFE
    if( performance.now() - start < 5000 ) {
    // recursive Promise chaining
    // all these promises will get executed before the next rendering
    // and block the UI rendering
    // even though we were in an rAF callback!
    return Promise.resolve()
    .then( lockUI );
    }
    } )();

    } );
    } );
    }, 0 );
    <p>Initial (please wait 5s)</p>

    细心的读者会注意到,这个脚本甚至没有将微任务排队到 。 7 事件循环的第 一步,但到 11.12 交错的微任务检查点。
    这只会更好地说明实际渲染仅在步骤 中完成的观点。 11.15 ,而且之前的任何事情实际上都可以延迟它。

    所以在你的测试用例中,“text”永远不应该是 呈现 , 因为通过拨打 Promise.resolve().then()您实际上将一个微任务排队,从事件循环的 Angular 来看,它实际上与此处的同步操作相同,因为在排队之后没有任何事情发生。
    除了 有案例无论如何,您仍然可以看到呈现的文本,如果浏览器输入 spin the event loop算法。如果浏览器面临一个很长的任务并决定它可以执行此算法,则可能会发生这种情况,这将允许渲染步骤发生,即使仍有很长的任务正在运行。
    例如,每当您启动像 alert() 这样的模式时,Firefox 都会执行此操作。或 prompt()等等。
    所以 在 Firefox 中 ,此代码段实际上将呈现文本 text , Chrome 不会在这里调用这个算法,所以它不会渲染任何东西,甚至不会渲染最初的 test :

    const p = document.querySelector('p');
    p.textContent = 'text';
    Promise.resolve().then(function microtask() {
    alert();
    p.textContent = 'Promise';
    });
    <p>test</p>

    然而 Chrome debugger 调用这个算法.所以这个关键字不会阻止渲染,这就是为什么你会看到 text被渲染。

    关于javascript - 任何证明在渲染之前执行微任务的示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62562845/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com