做者 • Dhanjiv Pandey • 本文出处 • 已得到中译受权
• 做者twitter
• 译者主页node
译者按: 2018年的文章,其中部分问题放在今天仍然不算过期。
简单的说 Node.js 就是运行在服务端的 JavaScript。 是一个基于Chrome JavaScript 运行时创建的一个平台。 c++
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度很是快,性能很是好。 web
Node.js是单线程的,它采用基于事件循环的并发模型。它不会阻塞代码运行 (译者:非阻塞I/O模型) ,而是注册一个容许应用程序继续运行的回调。这意味着Node.js能够处理并发操做而无需建立多个执行线程,所以能够很好地扩展 (译者:处理并发操做和扩展有什么直接关系?)。 是构建运行在分布式设备上的数据密集型实时程序的完美选择。shell
如下是使用Node.js的最佳领域:express
同时,它不适合那些占用较多CPU使用量的大型应用程序。编程
让咱们看一下Node.js的一些关键功能。segmentfault
咱们何时应该使用Node.js?浏览器
使用Node.js来开发流媒体或基于事件的实时应用程序是很是理想的,这些应用程序须要更少的CPU使用,好比:安全
Node.js很是适合须要同时处理数千个用户请求的服务。服务器
什么时候不使用Node.js?
下面列出了开发node.js应用程序最经常使用的IDE:
(译者:VSCode不写吗???VSCode吹爆!)
Node.js应用程序在调用时建立一个线程。每当Node.js收到请求时,服务器都会先完成其处理,而后再处理下一个请求。
Node.js经过使用事件循环和回调函数来异步工做,以并行处理多个请求。事件循环是一种处理外部事件并将其转换为回调函数的功能。它在适当的时间调用全部事件处理程序。这样,在处理单个请求时,大量工做是在后台完成的,所以,若是处理未完成,新的传入请求也没必要等待。
在处理请求时,Node.js会向其附加一个回调函数,并将其移至后台。如今,只要它的响应准备好了,就会调用一个事件,该事件触发关联的回调函数发送此响应。
让咱们以杂货店送货为例。
一般,送货员到每一个房子去运送包裹。Node.js以相同的方式工做,而且一次处理一个请求。当任何一所房子没有打开时,就会出现问题。送货员不能在一所房子停下来等它打开。他接下来要作的是打电话给房主,并要求他在房屋开门时打电话。同时,他将去其余地方送货。Node.js的工做方式相同。它不等待请求处理完成(房屋开放)。相反,它附加了一个回调函数(房屋全部者的呼叫)。每当请求处理完成(房屋开放)时,都会调用一个事件,该事件触发关联的回调函数发送响应。
To summarize, Node.js does not process the requests in parallel. Instead, all the back-end processes like, I/O operations, heavy computation tasks, that take a lot of time to execute, run in parallel with other requests.
总而言之,Node.js不会并行处理请求(单线程一次处理一个)。全部后台进程,如I/O操做、耗费大量时间执行的繁重计算任务,都与其余请求并行运行 (译者:这句话没有理解)。
REPL表明 “Read Eval Print Loop”。这是一个简单的程序,它接受命令,计算它们,最后打印结果。REPL提供了相似于Unix/Linux shell或窗口控制台的环境,咱们能够在其中输入命令,而后系统用输出进行响应。REPL执行如下任务:
是的,Node.js确实在一个线程上处理全部请求。但这只是Node.js设计理论的一部分。实际上,与单线程机制相比,它使用事件和回调来处理更大的异步请求。
此外,Node.js的优化设计利用了JavaScript和C++来保高性能。JavaScript经过Google Chrome v8引擎在服务器端执行。c++ lib的UV库经过后台来处理非顺序的I/O。
为了进行实际说明,让咱们假设在Node.js队列中排列了100个请求。按照设计,Node.js事件循环的主线线程将接收全部事件并转发给后台worker执行。一旦后台worker处理完请求,注册的回调将在事件循环线程上获得通知,将结果传递回用户。
下面是使用Node.js获取Post数据的代码片断:
app.use(express.bodyParser()); app.post('/', function(request, response){ console.log(request.body.user); });
下面是使用Node.js发出Post请求的代码片断:
var request = require('request'); request.post( 'http://www.example.com/action', { form: { key: 'value' } }, function (error, response, body) { if (!error && response.statusCode == 200) { console.log(body) } } );
咱们能够调用“回调”做为一个异步等效函数。Node.js大量使用回调,并在任务完成时触发回调。Node.js的全部API均以支持回调的方式编写。
例如,假设咱们有一个读取文件的函数,当它开始读取文件时,Node.js当即将控制权返回到执行环境,以便下一条指令能够执行。一旦文件读取操做完成,它将调用回调函数并将文件内容做为参数传递。所以文件I/O,没有阻塞或等待。此功能使Node.js具备高度可伸缩性,使用它能够处理大量请求,而无需等待任何函数返回指望的结果。
例如,假设咱们有一个读取文件的函数,当它开始读取文件时,Node.js当即将控制返回到执行环境,以便执行下一条指令。一旦文件读取操做完成,它将调用回调函数并传递文件的内容做为参数。所以,没有阻塞或等待,因为文件I/O。这个功能使得Node.js具备高度的可扩展性,使用它能够处理大量的请求,而不须要等待任何函数返回预期的结果。