0 html javascript css ecmascript-6
我是 JavaScript 新手,想知道“JS”如何处理异步操作。我开始知道它是在“事件循环”和“事件队列”的帮助下完成的,但我不知道其中的区别。有人可以帮我吗。
的一个例子asynchronous operations可以是:
function alpha(){
setTimeout(() => alert("hi"), 3000);
};
alpha();Run Code Online (Sandbox Code Playgroud)
事件循环是浏览器(或其他 JavaScript 主机)运行的循环,从事件队列(更常见的是作业或任务队列,列出等待处理的事件/作业/任务的队列)中拾取顶部项目并处理它,然后返回下一个并处理它,等等。
用伪代码术语来说(并且省略了很多细节):
// Event/job/task loop:
while (running) {
const task = taskQueue.pop();
if (task) {
task();
}
}
Run Code Online (Sandbox Code Playgroud)
JavaScript 代码或主机环境事件可能会将作业/任务添加到队列中,以便在循环到达它们时由循环拾取。
HTML 规范在此详细介绍了该过程。乍一看,在 HTML 规范中包含这些信息似乎很奇怪,但该规范不仅描述了 HTML(标记语言),还描述了用户代理(包括浏览器)应如何处理处理/呈现网页。
JavaScript 规范在这里讨论了这一点,尽管它没有详细说明主机应该执行哪种类型的循环,因为这是特定于主机的。
作为非浏览器 JavaScript 主机的示例,Node.js 文档在此处描述了其循环。
上面的伪代码中遗漏的更重要的细节之一是,几乎所有 JavaScript 主机中都至少有两个队列:主要队列(HTML 规范称为“任务队列”)和用于 Promise 反应的队列,以及可选的队列。其他东西(HTML 规范称为“微任务队列”)。所以这个工作循环看起来更像是:
// Event/job/task loop:
while (running) {
const task = taskQueue.pop();
if (task) {
task();
// Microtask loop:
while (!microtaskQueue.isEmpty()) {
const microtask = microtaskQueue.pop();
microtask();
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意微任务队列是如何在每个任务完成后清空的,这意味着如果任务队列中有任务 1、任务 2 和任务 3,并且在处理任务 1 的过程中将两个微任务添加到微任务队列中,则这些微任务会得到在任务 1 结束时、任务 2 之前运行。下面是一个示例:setTimeout将任务排队,但承诺反应(调用履行或拒绝处理程序)是微任务:
// Event/job/task loop:
while (running) {
const task = taskQueue.pop();
if (task) {
task();
}
}
Run Code Online (Sandbox Code Playgroud)
// Event/job/task loop:
while (running) {
const task = taskQueue.pop();
if (task) {
task();
// Microtask loop:
while (!microtaskQueue.isEmpty()) {
const microtask = microtaskQueue.pop();
microtask();
}
}
}
Run Code Online (Sandbox Code Playgroud)