我不是javascript的初学者。我实际上已经工作了3-4个月,但今天我读到了关于"什么是JavaScript的声明?"
JavaScript是单线程,非阻塞,异步,并发语言。
我迷路了。如果JavaScript是单线程的,它是如何并发的又是如何异步的,因为你需要跟踪你的异步代码正在做什么而没有另一个线程,是不是可以同时跟踪2个或更多代码?
答案 0 :(得分:5)
啊..这就是事情:
JavaScript是单线程的,但它有很多业余时间。
当它正在等待某些东西从网络上加载,或等待磁盘上的某些东西或等待操作系统将某些内容交还给它时,它可以运行其他代码。
setTimeout(function() {
// Do something later.
}, 1000);
当等待该超时返回执行该代码时,它可以运行来自OTHER超时的代码,或网络调用或系统中的任何其他异步代码。它一次只运行一个代码块,但这就是为什么我们说它是单线程的。
该线程可以反弹。很多。
而且,正如其他人所说,有网络工作者和服务工作者,但那些与你的主线程非常孤立。它们不能改变主线程背后的值。
每条评论更新
事件循环的工作原理是:
在处理事件时,确实阻止了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);
});
然后当有人点击文档时,我们的线程将进入无限循环,并且该窗口中的所有浏览器活动都将停止。甚至可以冻结整个浏览器,具体取决于您正在运行的浏览器。
最终,浏览器将有机会终止该任务,以便您恢复系统。
答案 1 :(得分:1)
如果您了解Webassembly,则通过本机编译的模块为Threads提出了一项提案
pthreads-style 阅读此git问题跟踪器link(1073)
继续 @Jeremy J Starcher 回答。
Javascript始终是使用异步,非阻塞和事件驱动的执行模型的单线程运行时。
要了解有关JS中事件循环执行的更多信息,我强烈建议您观看此内容 Youtube video。简单的解释 Philip Roberts 。
过去很好的日子,开发人员会使用
来绕过丛林来实现类似于线程的模型快进[>>> ] ECMA的多线程模型:
由于需要在JS引擎中生成一个线程以将少数较小的逻辑任务或网络代理任务卸载到单独的线程并专注于UI驱动的任务(如主线程上的表示和交互层),因此已经发生了变化。感。
考虑到这一要求,ECMA基本上提出了两个模型/ API来解决这个问题。
1. Web Worker:(SIC - Mozilla)
Web Workers可以在后台运行脚本操作 线程与Web应用程序的主执行线程分开。 这样做的好处是可以进行费力的处理 一个单独的线程,允许主(通常是UI)线程运行 没有被阻止/减速。
[ WebWorker可分为两个 ]
SharedWorker接口代表一种特定类型的工作者 可以从多个浏览上下文中访问,例如几个 窗户,iframe甚至工人。他们实现了一个接口 与专职工人不同,全球范围不同, SharedWorkerGlobalScope
Worker()
API但使用DedicatedWorkerGlobalScope
Worker是使用构造函数(例如Worker())创建的对象 运行一个命名的JavaScript文件 - 该文件包含将要执行的代码 在工作线程中运行;工人在另一个全球范围内运行 与当前窗口不同。这个上下文用a表示 专职工作人员的DedicatedWorkerGlobalScope对象
2. Service Worker (SIC - Mozilla)
服务工作者本质上充当位于Web之间的代理服务器 应用程序,浏览器和网络(如果可用)。他们是 旨在(除其他外)使创造有效 离线体验,拦截网络请求和接受 根据网络是否可用而采取适当行动 更新的资产驻留在服务器上。他们也将允许访问 推送通知和后台同步API。
一个示例用法是在 PWA - 渐进式网络应用下载脚本,延迟加载资源。
在HTML5Rocks上通过 Eric Bidelman 阅读此article关于代码本身和实现的详细解释
答案 2 :(得分:0)
JavaScript可能是“单线程”(我不确定是否真的如此),但你可以使用/ create webworkers在主线程之外运行javascript。
所以你可以同时运行两段代码。
我认为说一种语言就是这种或那种语言是错误的,当我们真正的意思是我们的程序就是这样或那样。
例如:NodeJS是单线程的,可以运行代码异步,因为它使用事件驱动的行为。 (有东西出现并触发一个事件...... Node处理它,如果它像在线请求那样,它做其他事情而不是等待响应......当响应到来时,它会触发一个事件和Node捕获它做任何需要做的事情。)
所以Javascript是......
单线程?不,因为你可以使用WebWorkers作为第二个线程
非阻塞?您可以编写阻止主线程的代码。只需构建一个执行一亿次或不使用回调的for
异步?不,除非您使用回调
并发?是的,如果您使用网络工作者,回调或承诺(实际上是回调)。