首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DOMContentLoaded事件和任务队列

DOMContentLoaded事件和任务队列
EN

Stack Overflow用户
提问于 2022-03-02 06:06:46
回答 1查看 125关注 0票数 0

我听说有三个队列在事件循环处理模型中有任务。

  1. MacroTaskQueue :此队列具有setTimeout、setInterval ..etc的回调函数
  2. MicroTaskQueue :这个队列有承诺的回调函数,mutationOberver ..etc
  3. AnimationFrameQueue :这个队列具有requestAnimationFrame的回调函数。

所以,我想知道的是

  • 谁会触发DOMContentLoaded事件?
  • DOMContentLoaded的回调函数在哪里排队?MacroTaskQueue还是MicroTaskQueue?
  • 最后,
代码语言:javascript
复制
var a = 10;
console.log(a);

setTimeout(function b() { console.log('im b'); }, 1000);

在这个代码中,

代码语言:javascript
复制
var a = 10;
console.log(a);

这段代码是否也在MacroTaskQueue或MicroTaskQueue中排队?

或者只有b在(min) 1000 is后在MacroTaskQueue中排队?

我在黑洞里。请帮帮我:D

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-03 06:52:57

您所称的"MacroTaskQueue“实际上是由几个任务队列组成的,其中任务正在排队。(请注意,规范只使用多个任务来源,实际上可能有一个任务队列)。在事件循环处理开始时,浏览器将从哪个任务队列中选择下一个要执行的“主”任务。重要的是要明白,这些任务很可能根本不意味着任何JavaScript的执行,JS只是浏览器所做工作的一小部分。

在单个事件循环迭代中,微任务队列将被访问和清空几次。例如,每次JS调用堆栈已清空。 (即几乎每次JS回调执行之后),如果还不够,事件循环处理模型中就有固定的“执行一个微任务检查点”点。

虽然与队列类似,动画帧回调实际上存储在有序映射中,而不是存储在队列本身中,这允许对这些回调中的一个进行“队列”新回调,而不会在该回调之后立即退出队列。更重要的是,许多其他回调也被执行在同一时间,例如滚动事件、调整大小事件、Web动画步骤+事件、ResizeObserver回调等等。但是这个“更新呈现”步骤只是偶尔发生一次,通常是以监视器刷新速率进行。

但是,这并不能说明什么是DOMContentLoaded。

谁会触发DOMContentLoaded事件?

此事件是作为“终结”部分中文档解析步骤的一部分触发的。浏览器必须首先在DOM操作任务源上对任务进行排队。然后,浏览器将最终选择此任务作为事件循环第一步的一部分。一旦执行了此任务的步骤,事件就会被触发并发送到文档上。这只是浏览器将调用和内部调用的分派事件算法的一部分,直到它呼叫我们的侦听器的回调。

注意,这个文档解析步骤作为一个任务本身是非常有趣的,因为这是最明显的地方,您将有多个microtask-检查点交错在“主”任务中(例如,每个任务)。

DOMContentLoaded的回调函数在哪里排队?

回调函数没有排队,它在概念上存储在EventTarget的事件侦听器列表中。事实上,它存储在内存中,因为这里的EventTarget是一个DOM对象(文档),它很可能附在这个DOM对象上,尽管这是规范没有什么可说的实现细节,因为这对我们的web是透明的。

MacroTaskQueue还是MicroTaskQueue?

我希望你现在也能更好地理解。任务队列和微任务队列只存储任务和微任务,而不是回调。回调存储在其他地方,取决于回调的类型(例如定时器和事件存储在不同的“概念性”位置),然后一些任务或microtask的步骤将调用它们。

这段代码是否也在MacroTaskQueue或MicroTaskQueue中排队?

这取决于这个脚本是从哪里解析的。如果它是在经典的<script>标记中内联的,那么这将是我们已经讨论过的特殊解析任务。如果它来自<script src="url.js">,那么它将是从获取一个经典脚本排队的任务的一部分,但它也可以是微任务的一部分,例如,在模块脚本中的await之后,或者如果您愿意,甚至可以强迫它:

代码语言:javascript
复制
queueMicrotask(() => {
  console.log("in microtask");
  eval(document.querySelector("[type=myscript]").textContent);
  console.log("still in microtask");
});
console.log("in parsing task");
代码语言:javascript
复制
<script type="myscript">
var a = 10;
console.log(a);
setTimeout(function b() { console.log('im b'); }, 1000);
</script>

甚至从理论上讲,微任务变成“宏”任务也是可能的,尽管显然没有浏览器实现这一点。

所有这一切,虽然我个人觉得所有这些东西迷人,作为一个网页开发,你不应该阻止自己在它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71318123

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档