JavaScript Web浏览器中的事件循环

示例

绝大多数现代JavaScript环境都是根据事件循环工作的。这是计算机编程中的一个常见概念,从本质上讲意味着您的程序不断等待新事物发生,并且当新事物发生时对其做出反应。在主机环境调用到你的程序,在产卵事件循环,然后一个“转”或“嘀”或“任务”运行完成。当该回合结束时,主机环境会在发生所有其他事情之前等待其他事情发生。

一个简单的例子是在浏览器中。考虑以下示例:

<!DOCTYPE html>
<title>Event loop example</title>

<script>
console.log("this a script entry point");

document.body.onclick = () => {
  console.log("onclick");
};

setTimeout(() => {
  console.log("setTimeout callback log 1");
  console.log("setTimeout callback log 2");
}, 100);
</script>

在此示例中,主机环境是Web浏览器。

  1. HTML解析器将首先执行<script>。它将完成。

  2. 呼叫会setTimeout告知浏览器,在100毫秒后,它应将一个任务加入队列以执行给定的操作。

  3. 同时,事件循环然后负责不断检查是否还有其他事情要做:例如,渲染网页。

  4. 100毫秒后,如果事件循环由于其他原因不忙,它将看到setTimeout排队的任务,并运行该函数,并记录这两个语句。

  5. 在任何时候,如果有人单击身体,浏览器都会将一个任务发布到事件循环中以运行单击处理程序功能。事件循环不断地检查要执行的操作,因此可以看到并运行该功能。

您可以在此示例中看到事件循环调用JavaScript代码的几种不同类型的入口点的方式:

  • 该<script>元素被立即调用

  • 该setTimeout任务发布到事件循环和运行一次

  • 点击处理程序任务可以多次发布并每次运行

事件循环的每一轮都负责很多事情。其中只有一部分会调用这些JavaScript任务。有关详细信息,请参见HTML规范。

最后一件事:说每个事件循环任务“运行到完成”是什么意思?我们的意思是,通常不可能中断排队作为任务运行的代码块,并且永远不可能运行与另一代码块交错的代码。例如,即使您单击了完美的时间,也永远无法获得以上代码"onclick"在两个setTimeout callback log 1/2"s之间登录。这是由于任务发布的工作方式所致。它是合作的且基于队列的,而不是抢占式的。