啊..事情是这样的:
JavaScript 是单线程的,但它有很多空闲时间。
当它等待某些东西从网络中加载出来,或者它正在等待某些东西从磁盘上或者等待操作系统将某些东西交还给它时,它可以运行其他代码。
setTimeout(function() {
// Do something later.
}, 1000);
在等待该超时以返回执行该代码时,它可以运行来自其他超时的代码、网络调用或系统中的任何其他异步代码。然而,它一次只运行一个代码块,这就是为什么我们说它是单线程的。
那个线程可以反弹。很多。
而且,正如其他人所说,有网络工作者和服务工作者,但它们与您的主线程非常隔离。他们不能在你的主线程背后改变值。
根据评论更新
事件循环的工作原理:
JavaScript 在处理 事件时确实被阻塞了。在代码运行时,该页面中的其他任何内容(假设浏览器主线程)都无法运行。
它不是像在 C 或 C++ 中那样的文字 event loop,就 JS 而言。这只是等待发生的事件。
/// Sample code
document.addEventListener("click", function() { /* Handle click */ });
window.addEventListener("load", function() { /* handle load */ });
在这种情况下,我们的代码中有两个事件监听器。 JS 引擎将编译,然后执行这两个语句。然后,出于所有意图,在等待某事发生的同时“睡觉”。 实际上,同一个线程可能会处理各种管理任务,例如绘制 HTML 页面、监听移动动作和发出各种事件,但这对于本次讨论无关紧要。
然后,一旦页面的其余部分被加载,浏览器将发出一个load 事件,该事件将被监听器捕获并运行更多代码。
然后它会回到空闲状态,直到有人点击文档,然后运行更多代码。
如果我们把代码改成这样:
document.addEventListener("click", function() {
while(true);
});
然后当有人点击文档时,我们的线程将进入无限循环,并且该窗口中的所有浏览器活动都将停止。甚至可能冻结整个浏览器,具体取决于您正在运行的浏览器。
最终,浏览器将有机会终止该任务,以便您恢复系统。