我听说有三个队列在事件循环处理模型中有任务。
所以,我想知道的是
var a = 10;
console.log(a);
setTimeout(function b() { console.log('im b'); }, 1000);在这个代码中,
var a = 10;
console.log(a);这段代码是否也在MacroTaskQueue或MicroTaskQueue中排队?
或者只有b在(min) 1000 is后在MacroTaskQueue中排队?
我在黑洞里。请帮帮我:D
发布于 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之后,或者如果您愿意,甚至可以强迫它:
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>
甚至从理论上讲,微任务变成“宏”任务也是可能的,尽管显然没有浏览器实现这一点。
所有这一切,虽然我个人觉得所有这些东西迷人,作为一个网页开发,你不应该阻止自己在它。
https://stackoverflow.com/questions/71318123
复制相似问题