首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在JavaScript中多线程或异步代码是如何工作的?

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

Stack Overflow用户
提问于 2016-03-26 08:04:52
回答 3查看 1.3K关注 0票数 3

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

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

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-03-26 08:57:03

啊.。事情是这样:

JavaScript是单线程的,但它有大量的空闲时间。

当它在等待从网络上加载的东西,或者等待磁盘之外的东西,或者等待操作系统将东西送回给它时,它可以运行其他代码。

代码语言:javascript
复制
setTimeout(function() {
  // Do something later.
}, 1000);

在等待超时以返回该代码时,它可以从系统中的其他超时、网络调用或任何其他异步代码中运行代码。但是,它一次只运行一段代码,这就是为什么我们说它是单线程的。

那条线可以来回弹跳。很多。

而且,就像其他人说的,有网络工作者和服务工作者,但是这些工作人员与您的主线程非常隔离。它们不能在主线程背后更改值。

按评论更新

事件循环的工作方式是:

  • 等待事件
  • 处理那个事件。

实际上,JavaScript在处理事件时会被阻塞。当代码正在运行时,该页面中的其他内容(假设浏览器主线程)无法运行。

它并不像在C或C++中那样是一个字面上的event loop,对于JS来说则不是。这只是等待发生的事情。

代码语言:javascript
复制
/// Sample code
document.addEventListener("click", function() { /* Handle click */ });

window.addEventListener("load", function() { /* handle load */ });

在本例中,在代码中有两个事件侦听器。JS引擎将编译,然后执行这两个语句。然后,对于所有的意图,“睡觉”,而等待什么事情发生。在现实中,同样的线程可以处理各种各样的家务任务,比如绘制HTML页面、监听移动动作和发布各种事件,但这对本文的讨论并不重要。

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

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

如果我们将代码更改为:

代码语言:javascript
复制
document.addEventListener("click", function() {
  while(true);
});

然后,当有人单击文档时,我们的线程将进入一个没完没了的循环,该窗口中的所有浏览器活动都将停止。甚至可能会冻结整个浏览器,这取决于您在哪个浏览器中运行。

最终,浏览器将给你一个机会来终止这个任务,这样你就可以让你的系统恢复正常。

票数 8
EN

Stack Overflow用户

发布于 2017-06-30 09:18:21

最新更新

如果您知道组件,那么就有一个通过本地编译模块实现线程的建议。

pthreads-style阅读了这个git问题跟踪器链接(1073)

继续使用@Jeremy 应答。

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

要了解JS中事件循环执行的更多信息,我强烈建议您观看此Youtube视频。简单精妙的解释菲利普罗伯茨

好的过去,开发人员会绕圈子来实现类似于线程模型的使用

  • 具有0毫秒的setTimeout或setIntervals:基本上指示引擎在引擎处于空闲状态或在http请求期间以等待模式执行非琐碎任务,或者通过以某种循环方式来回切换来执行代码。
  • 隐藏的Iframe:在带有桥的沙箱中运行JS代码,以便从父级到iframe之间进行通信,反之亦然。从技术上讲,Iframe不是在单独的线程上运行,而是以假线程的形式完成任务。

利用快速转发>>>到多线程模型

由于需要在JS引擎中生成一个线程,将少数较小的逻辑任务或网络代理任务卸载到单独的线程上,并集中于UI驱动的任务(如主线程上的表示和交互层),这是有意义的。

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

1.网络工作者: (SIC )

Workers使在后台线程中运行脚本操作成为可能,而后台线程与Web应用程序的主执行线程是分开的。这样做的优点是可以在单独的线程中执行辛苦的处理,允许主线程(通常是UI)运行,而不会被阻塞/减慢。

WebWorker可以分成两个

SharedWorker接口代表了一种特定类型的工作人员,可以从多个浏览上下文(如几个窗口、iframes甚至工人)访问。它们实现了一个不同于专用工作人员的接口,并且具有不同的全局范围,SharedWorkerGlobalScope

  • 专用工作人员:与Webworker相同,使用Worker() API创建,但使用DedicatedWorkerGlobalScope

Worker是使用运行命名JavaScript文件的构造函数(例如Worker())创建的对象--该文件包含将在辅助线程中运行的代码;工作人员运行在与当前窗口不同的另一个全局上下文中。在专用工作人员的情况下,此上下文由DedicatedWorkerGlobalScope对象表示。

2.服务工作者 (SIC )

服务工作者本质上充当位于web应用程序、浏览器和网络之间的代理服务器(如果可用的话)。它们的目的是(除其他外)能够创建有效的脱机体验,拦截网络请求,并根据网络是否可用和更新的资产是否驻留在服务器上采取适当的行动。它们还允许访问推送通知和后台同步API。

一个例子是在PWA中--进步web应用程序下载脚本,懒洋洋地加载资产。

阅读本文章,由Eric Bidelman介绍HTML5Rocks,对代码本身和实现做好解释

票数 2
EN

Stack Overflow用户

发布于 2016-03-26 08:33:59

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

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

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

例如: NodeJS是单线程的,可以异步运行代码,因为它使用事件驱动的行为。(事情发生了,引发了一件事.节点处理它,如果它类似于一个在线请求,它会做其他事情而不是等待响应.当响应到来时,它触发一个事件,Node捕获它并做任何需要做的事情)。

所以Javascript ..。

single-threaded?否,因为您可以使用WebWorkers作为第二个线程

非阻塞?,您可以编写阻止主线程的代码.只需构建一个执行了一亿次或不使用回调的for。

异步?否,除非您使用回调。

并发?是的,如果您使用webworkers、回调或承诺(这实际上是回调)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36233028

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档