简体   繁体   English

DOMContentLoaded 事件和任务队列

[英]DOMContentLoaded event and task queue

I heard that there are three queues which have tasks in Event Loop Processing Model.听说有3个队列在Event Loop Processing Model有任务。

  1. MacroTaskQueue: this queue have callback functions of setTimeout, setInterval..etc MacroTaskQueue:这个队列有setTimeout、setInterval等回调函数
  2. MicroTaskQueue: this queue have callback functions of promise, mutationOberver..etc MicroTaskQueue:这个队列有promise、mutationOberver..等回调函数
  3. AnimationFrameQueue: this queue have callback functions of requestAnimationFrame. AnimationFrameQueue:这个队列有requestAnimationFrame的回调函数。

So, what i'm wondering is that所以,我想知道的是

  • Who fires DOMContentLoaded event?谁触发 DOMContentLoaded 事件?
  • Where the callback function of DOMContentLoaded is queued? DOMContentLoaded 的回调 function 在哪里排队? MacroTaskQueue or MicroTaskQueue?宏任务队列还是微任务队列?
  • finally,最后,
var a = 10;
console.log(a);

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

in this code,在这段代码中,

var a = 10;
console.log(a);

is this code also queued in MacroTaskQueue or MicroTaskQueue?这段代码是否也在 MacroTaskQueue 或 MicroTaskQueue 中排队?

or only the b is queued in MacroTaskQueue after (min) 1000ms?或者只有b在(分钟)1000 毫秒后在 MacroTaskQueue 中排队?

Im in black hole.我在黑洞里。 Help me please:D请帮助我:D

What you call the "MacroTaskQueue" is actually made of several task-queues , where tasks are being queued.你所说的“MacroTaskQueue”实际上是由几个任务队列组成的, 任务正在排队。 (Note that the specs only use multiple task-sources , there could actually be a single task-queue). (请注意,规范仅使用多个任务源,实际上可能只有一个任务队列)。 At the beginning of the event-loop processing , the browser will choose from which task queue it will pick the next "main" task to execute.事件循环处理开始时,浏览器将从哪个任务队列中选择下一个要执行的“主要”任务。 It's important to understand that these tasks may very well not imply any JavaScript execution at all, JS is only a small part of what a browser does.重要的是要理解这些任务可能根本不意味着任何 JavaScript 执行,JS 只是浏览器所做的一小部分。

The microtask-queue will be visited and emptied several times during a single event-loop iteration.在单个事件循环迭代期间,将多次访问和清空微任务队列。 For instance every time that the JS call stack has been emptied (ie after almost every JS callback execution) and if it wasn't enough there are fixed "Perform a microtask checkpoint" points in the event-loop processing model .例如,每次JS 调用堆栈被清空(即在几乎每次 JS 回调执行之后)并且如果还不够,则在事件循环处理 model中有固定的“执行微任务检查点”点。

While similar to a queue, the animation frame callbacks are actually stored in an ordered map, not in a queue per se, this allows to "queue" new callbacks from one of these callbacks without it being dequeued immediately after.虽然与队列类似,animation 帧回调实际上存储在有序的 map 中,而不是队列本身,这允许从这些回调之一“排队”新回调,而不会在之后立即出队。 More importantly, a lot of other callbacks are also executed at the same time , eg the scroll events, resize events, Web animation steps + events, ResizeObserver callbacks, etc. But this "update the rendering" step happens only once in a while, generally at the monitor refresh rate.更重要的是,很多其他回调也同时执行,例如滚动事件、调整大小事件、Web animation 步+事件、ResizeObserver 回调等。但是这个“更新渲染”步骤只是偶尔发生一次,通常以显示器刷新率。

But, that's not saying much about DOMContentLoaded.但是,这并没有说明 DOMContentLoaded。

Who fires DOMContentLoaded event?谁触发 DOMContentLoaded 事件?

This event is fired as part of the Document parsing steps, in the "the end" section.此事件作为文档解析步骤的一部分在“结束”部分触发。 The browser has to first queue a task on the DOM manipulation task-source.浏览器必须首先在 DOM 操作任务源上排队任务。 This task will then eventually get selected by the browser as part of the first step of the event-loop.该任务最终将被浏览器选择为事件循环第一步的一部分。 And once this task's steps will be executed, the event will be fired and dispatched on the Document.一旦执行此任务的步骤,事件将被触发并在文档上分派。 That's only as part of this dispatch an event algorithm that the browser will invoke and inner-invoke until it calls our listener's callback.这只是作为分派事件算法的一部分,浏览器将调用内部调用该事件算法,直到它 调用我们的侦听器的回调。
Note that this Document parsing step is in itself quite interesting as a task since this is the most obvious place where you will have multiple microtask-checkpoints interleaved inside the "main" task (at each <script> for instance).请注意,这个文档解析步骤本身作为一项任务非常有趣,因为这是最明显的地方,您将在“主”任务(例如每个 <script> )中交错多个微任务检查点。

Where the callback function of DOMContentLoaded is queued? DOMContentLoaded 的回调 function 在哪里排队?

The callback function is not queued, it is conceptually stored in the EventTarget's event listener list .回调 function 没有排队,它在概念上存储在 EventTarget 的事件监听器列表中 In the facts, it's stored in memory, since here the EventTarget is a DOM object (Document), it's probably attached to this DOM object, though this is an implementation detail on which the specs have little to say as this is transparent to us web-devs.事实上,它存储在 memory 中,因为这里的 EventTarget 是一个 DOM object(文档),它可能附加到这个 DOM object,尽管这是一个实现细节,规范没有什么可说的,因为这对我们 web 是透明的-开发人员。

MacroTaskQueue or MicroTaskQueue?宏任务队列还是微任务队列?

As I hope you now understand better, neither.我希望你现在能更好地理解,两者都不是。 Task queues and the microtask-queue only store tasks and microtasks, not callbacks.任务队列和微任务队列只存储任务和微任务,不存储回调。 The callbacks are stored elsewhere, depending on what kind of callbacks they are (eg timers and events are stored in different "conceptual" places), and some task or microtask's steps will then call them.回调存储在别处,这取决于它们是什么类型的回调(例如,计时器和事件存储在不同的“概念”位置),然后某些任务或微任务的步骤将调用它们。

is this code also queued in MacroTaskQueue or MicroTaskQueue?这段代码是否也在 MacroTaskQueue 或 MicroTaskQueue 中排队?

That depends where this script has been parsed from.这取决于这个脚本是从哪里解析出来的。 If it's inline in a classic <script> tag, then that would be the special parsing task we already talked about.如果它内嵌在经典的<script>标签中,那么这就是我们已经讨论过的特殊解析任务。 If it's from a <script src="url.js"> , then it will be part of a task queued from fetch a classic script , but it can also be part of a microtask, eg if after an await in a module script, or you can even force it to be if you want:如果它来自<script src="url.js"> ,那么它将是从fetch a classic script排队的任务的一部分,但它也可以是微任务的一部分,例如,如果在模块脚本中await之后,或者如果你愿意,你甚至可以强迫它:

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

And it is even theoretically possible by specs that a microtask becomes a "macro-"task, though no browser does implements this anymore apparently. 根据规范,从理论上讲,微任务甚至有可能成为“宏”任务,尽管显然没有浏览器确实实现了这一点。
All this to say, while I personally find all this stuff fascinating, as a web-dev you shouldn't block yourself on it.综上所述,虽然我个人觉得所有这些东西都很吸引人,但作为网络开发者,你不应该在这上面阻止自己。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM