为什么node.js是异步的?

Joe*_*Joe 49 javascript multithreading asynchronous synchronous node.js

实际上没有人问过这个问题(来自我提出的所有"建议"以及我在这里询问之前的搜索).

那么为什么node.js是异步的呢?

根据我在一些研究后得出的结论:

像PHP和Python这样的语言是脚本语言(我可能错误的是脚本语言的实际语言),而JavaScript则不然.(我想这源于JS不编译的事实?)

Node.js在单个线程上运行,而脚本语言使用多个线程.

异步意味着无状态,并且连接是持久的,而同步是(几乎)相反的.

也许答案是在上面所说的地方找到的,但我仍然不确定.

我与本主题相关的第二个也是最后一个问题是:

JavaScript可以成为同步语言吗?

PS.我知道有些人会问"你为什么要让JS同步?" 在你的答案中,但事实是我没有.我只是问这些类型的问题,因为我确信那里有更多的人,而不仅仅是我自己想过这些问题.

bea*_*mit 57

Node.js在单个线程上运行,而脚本语言使用多个线程.

不是技术上的.Node.js使用多个线程,但只使用一个执行线程.后台线程用于处理IO以使所有异步良好工作.有效处理线程是一种巨大的痛苦,因此下一个最佳选择是在事件循环中运行,以便在IO上阻止后台线程时运行代码.

异步意味着无状态,并且连接是持久的,而同步是(几乎)相反的.

不必要.您可以非常轻松地在异步系统中保留状态.例如,在Javascript中,您可以使用bind()绑定this到函数,从而在函数返回时显式保留状态:

function State() {
    // make sure that whenever doStuff is called it maintains its state
    this.doStuff = this.doStuff.bind(this);
}
State.prototype.doStuff = function () {
};
Run Code Online (Sandbox Code Playgroud)

异步意味着不等待操作完成,而是注册一个监听器.这种情况一直发生在其他语言中,特别是需要接受用户输入的任何事情.例如,在Java GUI中,您不会阻止等待用户按下按钮,而是使用GUI注册侦听器.

我与本主题相关的第二个也是最后一个问题是:

JavaScript可以成为同步语言吗?

从技术上讲,所有语言都是同步的,甚至是Javascript.但是,Javascript在异步设计中工作得更好,因为它被设计为单线程.

基本上有两种类型的程序:

  • CPU绑定 - 使其更快的唯一方法是获得更多的CPU时间
  • IO界限 - 花费大量时间等待数据,因此更快的处理器无关紧要

视频游戏,数字计算器和编译器受CPU限制,而Web服务器和GUI通常是IO绑定的.Javascript相对较慢(因为它有多复杂),所以它无法在CPU绑定场景中竞争(相信我,我已经写了我公平分享的CPU绑定Javascript).

Javascript不仅可以根据类和对象进行编码,而且可以根据可以串联在一起的简单函数进行编码.这在异步设计中非常有效,因为可以编写算法来逐步处理数据.IO(特别是网络IO)非常慢,因此数据包之间有相当长的时间.

假设您有1000个实时连接,每个连接每毫秒提供一个数据包,处理每个数据包需要1微秒(非常合理).我们还假设每个连接发送5个数据包.

在单线程同步应用程序中,每个连接都将按顺序处理.所花费的总时间是(5*1 + 5*.001)*1000毫秒,或~5005毫秒.

在单线程异步应用程序中,每个连接将并行处理.由于每个数据包需要1毫秒,处理每个数据包需要0.001毫秒,我们可以处理数据包之间的每个连接数据包,因此我们的公式变为:1000*.001 + 5*1毫秒,或~6毫秒.

解决此问题的传统方法是创建更多线程.这解决了IO问题,但是当连接数量增加时,内存使用量(线程占用大量内存)和CPU使用率(将100个线程复用到1个核心比1个核心上的1个线程更难).

但是,有缺点.如果您的Web应用程序碰巧也需要进行大量的数字运算,那么您就是SOL,因为当您处理数字时,连接需要等待.线程解决了这个问题,因为当数据准备好等待IO的线程时,操作系统可以交换CPU密集型任务.此外,node.js绑定到单个核心,因此除非您启动多个实例和代理请求,否则无法利用多核处理器.


Cas*_*ynn 33

Javascript不会编译成任何东西.它在运行时被"评估",就像PHP和Ruby一样.因此它就像PHP/Ruby一样是一种脚本语言.(它的官方名称实际上是ECMAScript).

Node遵循的"模型"与PHP/Ruby略有不同.Node.js使用"事件循环"(单个线程),其目标是获取网络请求并快速处理它们,并且如果由于任何原因它遇到需要一段时间的操作(API请求,数据库查询 - 基本上任何涉及IO(输入/输出)的东西都会将其传递给后台"工作者"线程,并在工作线程等待长任务完成时继续执行其他操作.当发生这种情况时,主"事件循环"将获取结果并继续处理它们.

PHP/Ruby遵循线程模型.实质上,对于每个传入的网络请求,应用程序服务器都会旋转一个isloated线程或进程来处理请求.这种方法的扩展性不是很好,与此模型相比,Node的方法被认为是其核心优势之一.

异步意味着无状态,并且连接是持久的,而同步是(几乎)相反的.

否.同步指令按照自然顺序完成,从头到尾.异步指令意味着如果程序流程中的一个步骤需要相对较长的时间,程序将继续执行操作,并在完成时简单地返回此操作.

JavaScript可以成为同步语言吗?

JavaScript中的某些操作是同步的.其他人是异步的.例如:


阻止操作:

for(var k = 0; k < 1; k = k - 1;){
  alert('this will quickly get annoying and the loop will block execution')
alert('this is blocked and will never happen because the above loop is infinite');
Run Code Online (Sandbox Code Playgroud)

异步:

jQuery.get('/foo', function (result) { alert('This will occur 2nd, asynchronously'); });
alert('This will occur 1st. The above operation was skipped over and execution continued until the above operation completes.');
Run Code Online (Sandbox Code Playgroud)

  • *Javascript不会编译成任何东西.*是错误的.Node.js使用V8,它包含一个JIT编译器,可以将Javascript编译为机器代码.对于PHP,[有很多可以编译代码的解决方案](http://stackoverflow.com/a/1408499/510711).Ruby不评估源代码,而是在抽象语法树上运行. - >语言本身并不意味着它是否被解释或编译,但问题的具体实现并不是经典意义上的解释. (6认同)
  • @Fresheyeball _"V8首次执行时将JavaScript源代码直接编译成机器代码.没有中间字节代码,没有解释器."_参见[v8设计文档 - >动态机器代码生成](https://开发人员.google.com/V8 /设计#mach_code) (2认同)

Tre*_*xon 20

JavaScript可以成为同步语言吗?

Javascript不是"异步语言"; 相反,node.js有很多异步API.Asynchronous-ness是API的属性,而不是语言.可以在javascript中轻松创建和传递函数,这使得传递回调函数变得很方便,这是处理异步API中控制流的一种方法,但javascript没有任何本质上的异步.Javascript可以轻松支持同步API.

为什么node.js是异步的?

Node.js支持异步API,因为它是单线程的.这允许它有效地管理自己的资源,但要求长时间运行的操作是非阻塞的,异步API是一种允许通过大量非阻塞操作来控制流的方法.