javaScript如何工作?

我不是JavaScript的初学者。 实际上,我正在为此工作3-4个月,但今天我阅读了关于“什么是JavaScript?”的声明。

JavaScript是单线程的,非阻塞的,异步的并发语言。

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


啊..这是事情:

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);
    });
    

    那么当有人点击文档时,我们的线程将进入无限循环,并且该窗口中的所有浏览器活动都将停止。 根据你正在运行的是哪一个,甚至可能会冻结整个浏览器。

    最终,浏览器将有机会杀死该任务,以便让系统恢复。


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

    所以你可以同时运行两段代码。

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

    例如:NodeJS是单线程的,可以运行代码异步,因为它使用事件驱动的行为。 (有些东西出现并触发事件... Node处理它,如果它像在线请求那样,它执行其他事情而不是等待响应......当响应来临时,它触发一个事件并且节点捕获它并做任何需要做的事情)。

    所以Javascript是...
    单线程? 不,因为你可以使用WebWorkers作为第二个线程
    非阻塞? 你可以编写阻塞主线程的代码。 只需构建一个执行一亿次或不使用回调的方法即可。
    异步? 不,除非你使用回调。
    同时? 是的,如果你使用webworkers,回调或承诺(这真的是回调)。


    继续@Jeremy J Starcher的回答。

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

    要了解JS中事件循环执行的更多信息,请观看此Youtube视频。 菲利普罗伯茨简单的解释。

    过去的好日子,开发者会绕过布什实现类似于线程模式的使用

  • setTimeout为0 - 毫秒或setIntervals :基本上指示引擎在http请求期间引擎变为空闲或等待模式时执行不重要的任务,或者通过以循环方式间隔来回切换代码来执行代码。
  • 隐藏的iframe :在带有网桥的沙盒中运行JS代码,以便从父级到iframe进行通信,反之亦然。 技术上,Iframe不会在单独的线程上运行,而是将事情做成假线程。

  • 由ECMA快速转发[>>>]到多线程模型:

    关闭迟到的东西已经改变了,需要在JS引擎中产生一个线程,以将一些较小的逻辑任务或一个网络代理任务卸载到一个单独的线程,并专注于UI驱动的任务,如主线程上的表示层和交互层,这很有道理。

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

    1. Web Worker: (SIC - Mozilla)

    Web Workers使得可以在独立于Web应用程序的主执行线程的后台线程中运行脚本操作。 这样做的好处是可以在单独的线程中执行费力的处理,从而允许主(通常是UI)线程运行而不会被阻止/减慢。

    [ WebWorker可以分成两个 ]

  • 共享工作者
  • SharedWorker接口表示可以从多个浏览上下文(如多个窗口,iframe或甚至工作人员)访问的特定种类的工作人员。 它们实现的接口不同于专用工作者,并且具有不同的全局范围SharedWorkerGlobalScope。

  • 专用工作者:与使用Worker() API创建的Webworker相同,但使用DedicatedWorkerGlobalScope
  • Worker是一个使用构造函数(例如Worker())创建的对象,该构造函数运行指定的JavaScript文件 - 该文件包含将在工作线程中运行的代码; 工人在另一个与当前窗口不同的全球背景下运行。 在专职工作人员的情况下,此上下文由DedicatedWorkerGlobalScope对象表示


    2.服务工作者 (SIC - Mozilla)

    服务工作者实际上充当网络应用程序,浏览器和网络(如果可用)之间的代理服务器。 它们旨在(除其他外)创建有效的脱机体验,拦截网络请求并根据网络是否可用以及更新的资产驻留在服务器上采取适当的措施。 他们还将允许访问推送通知和后台同步API。

    一个示例用法是在PWA - 渐进式Web应用程序下载脚本,延迟加载资产的目的。


    Eric Bidelman在HTML5Rocks上阅读这篇文章对代码本身和实现的很好的解释

    链接地址: http://www.djcxy.com/p/79393.html

    上一篇: How does javaScript work?

    下一篇: Parallel versus Concurrent?