了解浏览器中的 JS 事件循环和渲染周期

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

在观看了这些关于 JS 事件循环和在浏览器中渲染的演讲之后(事件循环到底是什么?Web 浏览器事件循环、setTimeout、微任务、requestAnimationFrame...),我正在尝试什么类型的延迟会阻止浏览器中的渲染。

我正在测试这 4 种方法:

  • 同步长任务(演示中的
    delayLoop
    功能):这是我从演讲中了解到的行为。长任务会占用调用堆栈,因此浏览器无法将渲染推入堆栈。这会导致 UI 冻结,直到长任务完成为止。
  • Promise 解析回调运行长任务(演示中的
    delayPromise
    函数):这也具有类似的行为。这次,微任务(promise 的回调)使用长任务占用调用堆栈,这会推迟渲染任务直到完成。
  • 新的 Promise 回调在解析之前运行一个长任务(演示中的
    delayPromiseReturn
    函数):这也具有类似的行为。虽然我不明白的是为什么
    func
    的日志没有立即打印。我原本期望
    func
    能够完成,并在堆栈中运行承诺回调。
  • 运行长任务的
  • setTimeout 回调(演示中的
    delayTimeout
    函数):我理解这种行为。我原以为 UI 会在 5 秒后冻结,因为回调任务会占用调用堆栈并阻止渲染任务。相反,动画正常完成,回调任务也在后台正常完成(打印控制台日志),对渲染没有任何影响。

function delayLoop() {
    console.log('starting for loop')
    for(let i = 0; i < 10000000000; i++) {}
  console.log('ending for loop')
}

function delayPromise() {
    Promise.resolve().then(function() {
    console.log('starting promise')
    for(let i = 0; i < 10000000000; i++) {}
    console.log('ending promise')
  })
}

function delayPromiseReturn() {
    return new Promise(function(resolve) {
    console.log('starting await')
    for(let i = 0; i < 10000000000; i++) {}
    console.log('ending await')
    
    resolve()
  })
}

function delayTimeout() {
    setTimeout(function() {
    console.log('starting timeout')
    for(let i = 0; i < 10000000000; i++) {}
    console.log('ending timeout')
  }, 5000)
}

function func() {
    console.log('starting delay func')
    
  document.querySelector('.anim').classList.add('start')
    /* delayLoop() */
  /* delayPromise() */
  /* delayPromiseReturn() */
  
  delayTimeout()
  
  console.log('ending delay func')
}
.anim {
  height: 50px;
  width: 50px;
  background-color: blue;
}

@keyframes rotation {
  0% {
    transform: rotate(0deg);
  }
  
  100% {
    transform: rotate(90deg);
  }
}

.start {
  animation: rotation 1s linear 10;
}
<button onclick="func()">Click</button>
<div class="anim"></div>

对 Promise return (

delayPromiseReturn
) 和 setTimeout (
delayTimeout
) 行为有什么解释吗?如果我对其他点的理解有错误,请纠正我。

javascript async-await promise event-loop
1个回答
0
投票

CSS 和图像动画不会被 JS 屏蔽,所以你会看到它们正常运行。

© www.soinside.com 2019 - 2024. All rights reserved.