JavaScript中的多线程或异步代码是如何工作的?

JavaScript中的多线程或异步代码是如何工作的?,javascript,multithreading,asynchronous,Javascript,Multithreading,Asynchronous,我不是javascript的初学者。在过去的3-4个月里,我一直在研究这个问题,但今天我读了一篇关于“什么是JavaScript?” JavaScript是单线程、非阻塞、异步、并发语言 我迷路了。如果JavaScript是单线程的,它怎么可能是并发的,怎么可能是异步的,因为您需要跟踪异步代码正在做什么,如果没有另一个线程,就不可能同时跟踪2个或更多的代码 JavaScript可能是“单线程的”(我不确定是否真的是这样),但您可以使用/创建webworkers在主线程之外运行JavaScript

我不是javascript的初学者。在过去的3-4个月里,我一直在研究这个问题,但今天我读了一篇关于“什么是JavaScript?”

JavaScript是单线程、非阻塞、异步、并发语言


我迷路了。如果JavaScript是单线程的,它怎么可能是并发的,怎么可能是异步的,因为您需要跟踪异步代码正在做什么,如果没有另一个线程,就不可能同时跟踪2个或更多的代码

JavaScript可能是“单线程的”(我不确定是否真的是这样),但您可以使用/创建webworkers在主线程之外运行JavaScript

因此,您可以同时并行运行两段代码

我认为当我们真正的意思是我们的程序是这个或那个时,说语言是这个或那个是错误的


例如:NodeJS是单线程的,可以异步运行代码,因为它使用事件驱动的行为。(某个事件出现并触发事件…节点处理它,如果它类似于在线请求,则它会执行其他操作,而不是等待响应…当响应出现时,它触发事件,节点捕获它并执行任何需要执行的操作)

所以Javascript是…
单线程?否,因为您可以将WebWorkers用作第二个线程
非阻塞?您可以编写阻塞主线程的代码。只需构建一个执行1亿次或不使用回调的for。
异步?否,除非使用回调。
并发?是的,如果您使用webworkers、回调或承诺(实际上是回调)。

啊。。事情是这样的:

JavaScript是单线程的,但它有很多空闲时间

当它在等待从网络上加载一些东西,或者在等待从磁盘上加载一些东西,或者在等待操作系统将一些东西交还给它时,它可以运行其他代码

setTimeout(function() {
  // Do something later.
}, 1000);
当它等待超时返回执行该代码时,它可以运行来自其他超时、网络调用或系统中任何其他异步代码的代码。然而,它一次只运行一个代码块,这就是为什么我们说它是单线程的

那根线可以弹来弹去。很多

而且,正如其他人所说,有web工作人员和服务工作人员,但这些工作人员的运行与主线程非常隔离。它们不能在主线程背后更改值

根据评论更新

事件循环通过以下方式工作:

  • 等待事件
  • 处理那个事件
JavaScript确实在处理事件时被阻止。代码运行时,该页面中的任何其他内容(假定浏览器主线程)都无法运行

<>这不是文字或代码>事件循环< /C> > C或C++,而不是JS。这只是等待发生的事件

/// Sample code
document.addEventListener("click", function() { /* Handle click */ });

window.addEventListener("load", function() { /* handle load */ });
在本例中,我们的代码中有两个事件侦听器。JS引擎将编译,然后执行这两条语句。然后,不管怎样,在等待事情发生的时候“睡觉”。实际上,同一个线程可能会处理各种内部管理任务,如绘制HTML页面、监听移动动作和发出各种事件,但这对本次讨论并不重要

然后,一旦加载了页面的其余部分,浏览器将发出一个
load
事件,侦听器将捕获该事件并运行更多的代码

然后它将返回到空闲状态,直到有人单击文档,然后会运行更多代码

如果我们将代码更改为:

document.addEventListener("click", function() {
  while(true);
});
然后,当有人单击文档时,我们的线程将进入无休止的循环,该窗口中的所有浏览器活动都将停止。甚至可能冻结整个浏览器,具体取决于您运行的浏览器

最终,浏览器将有机会终止该任务,以便您可以恢复系统。

最新更新 如果您知道有关于via本机编译模块的建议

pthreads样式阅读此git问题跟踪器


继续回答
@Jeremy J Starcher

Javascript始终是单线程运行时,使用异步、非阻塞和事件驱动的执行模型

要了解更多关于JS中事件循环执行的信息,我强烈建议您观看这篇文章 . 菲利普·罗伯茨(Philip Roberts)的精彩解释

在过去的好日子里,开发人员会千方百计地使用线程实现类似的模型

  • 设置超时0-毫秒或设置间隔:基本上指示引擎在http请求期间处于空闲或等待模式时执行非平凡任务,或者以类似循环的方式来回切换以执行代码
  • 隐藏的Iframe:在一个带有网桥的沙箱中运行JS代码,以便从父级到Iframe进行通信,反之亦然。从技术上讲,Iframe不在单独的线程上运行,而是作为伪线程完成任务

通过ECMA快速转发[>>>]到多线程模型:

随着在JS引擎中生成一个线程以将一些较小的逻辑任务或网络代理任务卸载到一个单独的线程中,并将精力集中在UI驱动的任务上(如主线程上的表示和交互层)的要求的改变,最近的情况已经发生了变化

考虑到这一需求,ECMA提出了两个模型/API来基本解决这一问题

(原文如此-Mozilla)

Web Workers使在后台运行脚本操作成为可能 与web应用程序的主执行线程分离的线程。 这样做的好处是可以在计算机中执行费力的处理 一个单独的线程,允许主线程(通常是UI)运行 不被阻挡/减速,做什么