翻译:疯狂的技术宅
原文: https://medium.freecodecamp.o...


本文首发微信公众号:前端先锋
欢迎关注,每天都给你推送新鲜的前端技术文章


Node.js 是一个 JavaScript 运行时环境。听起来还不错,不过这究竟意味着什么?它又是如何运作的?

Node 运行时环境包含执行 JavaScript 程序所需要的一切。

clipboard.png

如果你了解 Java 的话,会发现它们有点像。

JavaScript 原来是只能在浏览器中运行的,当把它扩展成为可以在你的计算机上作为独立的程序运行时,Node.js 就出现了。

现在你可以用 JavaScript 做更多的事情,而不仅仅是用在网站的互动和特效上。

JavaScript 现在能够去做其他脚本语言(如Python)可以执行的操作。

你 Chrome 浏览器中的 JavaScript 和 Node.js 都在 V8 引擎上运行。该引擎将你的 JavaScript 代码转换为更快的机器代码。机器代码是低级代码,计算机可以直接运行而无需先解释它。

为什么选择 Node.js?

这是 Node.js 官方网站上给出的正式定义:

Node.js®是基于 Chrome 的 V8 JavaScript 引擎构建的 JavaScript 运行时环境。

Node.js 使用事件驱动的非阻塞 I/O模型,轻量且高效。

Node.js 的包生态系统 npm 是世界上最大的开源库生态系统。

我们在前面已经讨论过了这个定义的第一行:“Node.js®是基于 Chrome 的 V8 JavaScript 引擎构建的 JavaScript 运行时环境。” 现在让我们理解剩下的两行,这样我们就可以找出为什么 Node.js 如此受欢迎的原因。

I/O 指的是输入/输出。它可以是从读取/写入本地文件到向 API 发出 HTTP 的任何内容。

I/O 需要时间,因此会阻止其他函数。

考虑一下这种情况,我们需要通过请求后端数据库来获取 user1 和 user2 的详细信息,然后在屏幕或控制台上打印它们。对该请求的响应需要时间,但是两个用户数据的请求可以独立地同时执行。

clipboard.png

阻塞 I/O(左)与非阻塞 I/O(右)

阻塞 I/O

在阻塞方法中,在 user1 的数据被输出到屏幕之前,不会启动 user2 的数据请求。

如果这是一个Web服务器,我们必须为每个新用户启动一个新线程。但 JavaScript 是单线程的(实际上不是真的,但它有一个单线程的事件循环,我们稍后会讨论)。所以这会使 JavaScript 不太适合多线程任务。

这就是非阻塞的用武之地。

非阻塞 I/O

另一方面,如果用非阻塞请求,可以在为 user2 发起数据请求时,无需先等待对 user1 请求的响应。你可以并行启动这两个请求。

这种非阻塞 I/O 消除了对多线程的需要,因为服务器可以同时处理多个请求。

JavaScript 事件循环

以下是 JavaScript 事件循环工作原理简要的逐步描述。

clipboard.png

  1. main() 送入调用栈。
  2. console.log() 送入调用栈。然后立即运行并弹出。
  3. setTimeout(2000) 送入栈。 setTimeout(2000)是一个 Node API。在调用它时,先注册事件回调。事件将等待 2000 毫秒,然后回调这个函数。
  4. API 中注册后,setTimeout(2000) 从调用堆栈中弹出。
  5. 现在第二个 setTimeout(0) 以相同的方式注册。我们现在有两个 Node API 等待执行。
  6. 等待 0 秒后,setTimeout(0) 被移动到回调队列,同样的事情发生在 setTimeout(2000)
  7. 在回调队列中,函数等待调用栈为空,因为每个语句都执行一次。这由事件循环处理。
  8. 最后一个 console.log() 运行,并且 main() 从调用栈中弹出。
  9. 如果事件循环检测到到调用堆栈为空且回调队列不为空。它将回调(以先进先出顺序)移动到调用栈并执行。

npm

clipboard.png

这些是由令人敬畏的社区所构建的库,它能解决你的大多数的常规问题。 npm(Node package manager))中有很多可以用在你的程序中包,可以使你的开发更快更有效。

Require

Require 做三件事:

  • 它从 Node.js API 加载与 Node.js 捆绑在一起的模块,如文件系统和 HTTP 等。
  • 它加载从 npm 安装的第三方库,如 Express 和 Mongoose 等。
  • 它允许你 require 自己的文件并把项目模块化。

Require 是一个函数,它接受参数 “path” 并返回 module.exports

Node 模块

Node 模块是一个可重用的代码块,它的存在不会对其他代码产生意外地影响。

你可以编写自己的模块并在各种程序中使用它。 Node.js 有一组内置模块,无需进一步安装即可使用。

V8 通过利用 C++ 来加速 JavaScript

V8 是一个用 C++ 编写的开源运行时引擎。

JavaScript => V8(C ++)=> 机器码

V8 实现了 ECMA-262 中指定的名为 ECMAScript 的脚本。 ECMAScript 由 Ecma International 创建,用于标准化JavaScript。

V8 可以独立运行,也可以嵌入到任何 C++ 程序中。它有一些钩子,允许你编写自己的C++代码供 JavaScript 使用。

这实际上允许你通过将 V8 嵌入到 C++ 代码中来向 JavaScript 添加功能,以便使你的 C++ 代码实现比 ECMAScript 标准更多的功能。

正如 Greg Bulmash 引起了我的注意,除了V8之外,还有许多不同的 JavaScript 引擎,如 Mozilla 的 SpiderMonkey,微软的 Chakra 等等。更多的东西可以在这里找到。

事件

事件指的是我们可以对在程序中发生的事情作出回应。Node 中有两种类型的事件。

  • 系统事件:来自用 C++ 实现的基于 libuv 库的内核。(例如,读取文件完毕)。
  • 自定义事件:JavaScript 核心。

在 Node.js 中写一个 Hello World

创建文件 app.js 并将以下内容添加到其中。

console.log("Hello World!");

打开终端,将目录切换到保存文件的文件夹,然后运行 node app.js

就这么简单,你在 Node.js 中写的 “Hello World” 跑起来了。

最后,你可以通过互联网上的大量资源去了解关于 Node.js 的更多信息。


本文首发微信公众号:前端先锋

欢迎扫描二维码关注公众号,每天都给你推送新鲜的前端技术文章

欢迎扫描二维码关注公众号,每天都给你推送新鲜的前端技术文章


欢迎继续阅读本专栏其它高赞文章:


本文固定链接: http://www.js-code.com/cpp/cpp_61370.html