绝大多数现代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浏览器。
HTML解析器将首先执行<script>。它将完成。
呼叫会setTimeout告知浏览器,在100毫秒后,它应将一个任务加入队列以执行给定的操作。
同时,事件循环然后负责不断检查是否还有其他事情要做:例如,渲染网页。
100毫秒后,如果事件循环由于其他原因不忙,它将看到setTimeout排队的任务,并运行该函数,并记录这两个语句。
在任何时候,如果有人单击身体,浏览器都会将一个任务发布到事件循环中以运行单击处理程序功能。事件循环不断地检查要执行的操作,因此可以看到并运行该功能。
您可以在此示例中看到事件循环调用JavaScript代码的几种不同类型的入口点的方式:
该<script>元素被立即调用
该setTimeout任务发布到事件循环和运行一次
点击处理程序任务可以多次发布并每次运行
事件循环的每一轮都负责很多事情。其中只有一部分会调用这些JavaScript任务。有关详细信息,请参见HTML规范。
最后一件事:说每个事件循环任务“运行到完成”是什么意思?我们的意思是,通常不可能中断排队作为任务运行的代码块,并且永远不可能运行与另一代码块交错的代码。例如,即使您单击了完美的时间,也永远无法获得以上代码"onclick"在两个setTimeout callback log 1/2"s之间登录。这是由于任务发布的工作方式所致。它是合作的且基于队列的,而不是抢占式的。