如果你正在考虑使用JavaScript进行后端开发,你会听到“Node.js”这个术语。Node通常与开发功能强大的web服务器联系在一起。
但 Node.js 究竟是什么?它是和 Angular 一样的 JavaScript 框架吗?它是一种编程语言吗?它是 JavaScript 库吗?它是一组技术的总称吗?或者它只是 JavaScript 的另一个词?
在本文中,我们将深入了解 Node.js 的世界,了解它是什么、为什么创建它以及它的用途。这不是一个基于项目的教程——它旨在向初学者介绍 Node 及其工作原理。
以下是我们将讨论的主题:
- Node.js的历史
- 什么是Node.js?
- Node.js是如何工作的?
- Node.js 中的模块
- 展望未来的 Node.js
如果你喜欢了解软件工具及其工作原理,那么你一定会喜欢阅读这篇文章。那么,让我们开始吧。
1、Node.js的历史
1995年,为网景公司工作的布兰登·艾奇(Brendan Eich)发明了JavaScript。但它是一种只能在浏览器上运行的编程语言。
网页最初只显示静态信息。JavaScript的发明满足了网页中更多交互行为的需求。有了这项发明,开发人员可以构建更动态的网页。
在Brendan Eich发明了JavaScript之后,许多公司也尝试使用这种语言来运行web服务器(服务器端脚本)。这些尝试包括网景的Livewire和微软的Active Server Pages。
但这从来没有成为开发web服务器的一种方式,即使JavaScript在浏览器中使用时继续获得流行。
2008年,谷歌发布了一款名为Chrome的新浏览器。这款浏览器的发布彻底改变了互联网浏览的世界。它是一个优化的浏览器,可以快速执行JavaScript,并改善了用户在 Web 上的体验。
Google Chrome 浏览器之所以能如此快速地执行 JavaScript 代码,是因为 Chrome 浏览器内运行着一个名为 V8 的 JavaScript 引擎。该引擎负责接收 JavaScript 代码,优化代码,然后在计算机上执行。
该引擎是客户端 JavaScript 的理想解决方案。谷歌 Chrome 浏览器成为领先的网络浏览器。
2009年,一位名叫Ryan Dahl的软件工程师批评了当时流行的后端服务器运行方式。最流行的构建Web服务器的软件是Apache HTTP服务器。Dahl认为它是有限的,因为它不能有效地处理大量的实时用户连接(10,000 +)。
这也是 Ryan Dahl 开发 Node.js 的主要原因之一。Node.js 使用谷歌的 V8 引擎来理解和执行浏览器外的 JavaScript 代码。这是一个以运行网络服务器为目的的程序。
Node.js 是传统 Apache HTTP 服务器的一个很好的替代品,并慢慢获得了开发者社区的认可。
如今,Netflix、NASA、LinkedIn、Paypal 等许多大型组织都在使用 Node.js。这些公司利用 Node.js 的功能为用户构建强大的应用程序。
此外,在撰写本文时,在最近的StackOverflow开发者调查中,Node.js被评为“Web框架和技术”类别中最受欢迎的技术。接下来展示了Node.js现在有多流行。
Source: https://survey.stackoverflow.co/2022/#technology-most-popular... Stack Overflow Developer Survey 2022
本文将深入探讨是什么让Node.js脱颖而出,以及它是如何工作的。但在此之前,我们需要确切地定义它是什么。
2、什么是Node.js?
从Node.js官网来看,它是这样说的:
Node.js 是一个开源、跨平台的 JavaScript 运行时环境。
为了定义Node.js,我们需要将定义分成几个部分。我们要定义的术语是:
- 开源
- 跨平台的
- 运行时环境
2.1、开放源代码是什么意思?
开放源代码通常用于描述公众可以检查和编辑其源代码的软件。这意味着任何人都可以检查使程序按其方式工作的代码。
这样做的一个好处是,程序的用户可以更好地了解程序及其功能。此外,如果一个人发现了一个bug,他们可以贡献并修复这个bug。
您可以在github上找到Node的源代码,github是显示开源代码的最流行的网站。Node.js在GitHub上也有很多贡献者——添加功能和修复错误的人。每个人都可以访问Node.js的源代码,如果他们愿意,甚至可以定制自己的程序版本。
2.2、跨平台是什么意思?
如果一个程序是跨平台的,就意味着该程序不局限于单一的操作系统或硬件架构。
跨平台程序可在多个平台上运行。Node.js 可在 Windows、Linux、Unix 和 MacOS 等平台上运行。开发人员可以在很多操作系统上使用 Node.js。
2.3、什么是运行环境?
编程语言的运行时环境是指用户可以执行用该语言编写的代码的任何环境。该环境提供运行代码所需的所有工具和资源。Node.js 是一种 JavaScript 运行时环境。
除了 Node.js,JavaScript 运行环境的另一个例子是网络浏览器。浏览器通常拥有执行客户端 JavaScript 代码所需的所有资源。
在浏览器中,我们可以使用 JavaScript 与标记元素交互并调整样式。浏览器会立即运行代码,因为它是一个运行时环境。
从上面定义的三个术语可以看出,Node.js不像Angular那样是一个JavaScript框架。Node.js不是一种编程语言,它不是一个JavaScript库,也不是一组技术的总称。它也不是JavaScript的另一个名称。
Node.js 是一种可以执行 JavaScript 代码的软件程序。更确切地说,Node.js 是一种 JavaScript 运行环境。它是一种为使 JavaScript 代码用于服务器端脚本而开发的环境。
3、Node.js是如何工作的?
Node.js主要是用C/C++编写的。作为一个应该运行web服务器的程序,Node.js需要不断地与设备的操作系统交互。
使用C等低级语言构建Node.js使软件可以轻松访问操作系统的资源并使用它们执行指令。
但是,Node.js 的工作原理还有很多复杂之处。Node.js 可运行快速高效的Web服务器,但它究竟是如何做到这一点的呢?本节将介绍 Node.js 实现高效的过程。
要了解 Node.js 的工作原理,我们必须了解三个主要组件。这些组件是
- V8引擎
- Libuv
- Event Loop
我们将深入研究并解释这些组件,以及它们如何组成Node.js。
3.1、什么是V8引擎?
V8引擎是在Chrome浏览器中解释和运行JavaScript代码的JavaScript引擎。其他一些浏览器使用不同的引擎,例如,Firefox使用SpiderMonkey, Safari使用JavaScriptCore。没有JavaScript引擎,计算机就无法理解JavaScript。
V8引擎包含一个内存堆和调用堆栈。它们是V8引擎的组成部分。它们帮助管理JavaScript代码的执行。
内存堆是V8引擎的数据存储。每当我们创建一个用JavaScript保存对象或函数的变量时,引擎就会将该值保存在内存堆中。为了简单起见,它类似于为徒步旅行者储存物资的背包。
每当引擎执行代码并遇到任何这些变量时,它都会从内存堆中查找实际值——就像每当徒步旅行者感到寒冷并想要生火时,他们可以查看背包中的打火机一样。
要了解内存堆,还有很多更深层次的东西。JavaScript 中的内存管理是一个需要花更多时间解释的话题,因为实际过程非常复杂。要了解有关内存堆的更多信息,请查看此资源。
调用栈是 V8 引擎的另一个构件。它是一种管理函数执行顺序的数据结构。每当程序调用一个函数时,该函数就会被放在调用栈上,只有当引擎处理完该函数后才能离开调用栈。
JavaScript 是一种单线程语言,这意味着它一次只能执行一条指令。由于调用堆栈包含要执行指令的顺序,这意味着 JavaScript 引擎只有一个顺序,一个调用堆栈。点击此处了解有关单线程和调用栈的更多信息。
3.2、什么是Libuv?
除了 V8 引擎,Node.js 的另一个非常重要的组件是 Libuv。Libuv 是一个用于执行输入/输出(I/O)操作的 C 语言库。
I/O 操作与向计算机发送请求和接收响应有关。这些操作包括读写文件、发出网络请求等。
Source: https://libuv.org
从 Libuv 的官方网站上可以看到,他们是这样说的:
Libuv 是一个多平台支持库,侧重于异步 I/O。
这意味着Libuv是跨平台的(可以在任何操作系统上运行),并且专注于异步I/O。
计算机处理 I/O 指令往往需要时间,但 Libuv(Node.js 用于与计算机接口的库)专注于异步 I/O。它可以同时处理多个 I/O 操作。
这就是 Node.js 在单线程的情况下仍能高效处理 I/O 指令的原因。这一切都要归功于 Libuv。Libuv 知道如何异步处理请求,从而最大限度地减少延迟。但 JavaScript 引擎究竟是如何利用 Libuv 的?
每当我们向 Node.js 传递脚本时,引擎就会解析代码并开始处理。调用堆栈会保存调用的函数并跟踪程序。如果 V8 引擎遇到 I/O 操作,它会将该操作传递给 Libuv。然后,Libuv 执行 I/O 操作。
请注意,Libuv 是一个 C 库。我们如何使用 JavaScript 代码来运行 C 指令?有一些绑定可以将 JavaScript 函数与其在 Libuv 中的实际实现连接起来。这些绑定使得使用 JavaScript 代码执行 I/O 指令成为可能。
Node.js 使用 Libuv 进行实际执行,但会公开应用编程接口 (API)。因此,我们现在可以使用 Node.js API(看起来像 JavaScript 函数)来启动 I/O 操作。
值得注意的是,JavaScript 的确是一种单线程语言,但 Node.js 使用的底层库 Libuv 可以在操作系统中执行指令时利用线程池(多线程)。
现在,您在使用 Node.js 时不必担心这些线程了。Libuv 知道如何有效地管理这些线程。您只需使用所提供的 Node.js API 编写指令即可。
Libuv 最初是为 Node.js 创建的,但现在不同的编程语言都对其进行了绑定。Julia 和 Luvit(基于 Lua 的运行环境)与 Node.js 一样内置了绑定,但其他语言也有提供这些绑定的库。例如 Python 中的 uvloop 等。
3.3、什么是 Event Loop?
Node.js 中的事件循环(Event Loop)是流程中非常重要的一部分。从名称上,我们可以看出它是一个循环。当 Node.js 开始执行程序时,循环就开始运行。在本节中,我们将探讨事件循环的作用。
当我们运行包含一些异步代码(如 I/O 指令或基于定时器的操作)的 JavaScript 程序时,Node.js 会使用 Node.js API 对其进行处理。异步函数通常会在函数处理完毕后执行一些指令。这些指令被放置在回调队列(Callback Queue)中。
回调队列采用先进先出(FIFO)方式工作。这意味着第一个进入队列的指令(回调)将首先被调用。
事件循环运行时,会检查调用栈是否为空。如果调用栈不空,它就会允许正在进行的进程继续。但如果调用栈为空,它就会将回调队列中的第一条指令发送给 JavaScript 引擎。然后,引擎会将该指令(函数)放入调用栈并执行。这与浏览器中事件循环的工作方式非常相似。
因此,事件循环使用Node.js中的JavaScript V8引擎执行异步指令的回调。这是一个循环,这意味着每次它运行时,它都会检查调用堆栈,以知道它是否会删除最前面的回调并将其发送给JavaScript引擎。
Node.js据说有一个事件驱动的架构。这意味着Node.js是围绕侦听事件并在事件发生时及时响应而构建的。这些事件可以是定时器事件、网络事件等等。
Node.js 通过使用事件循环来响应这些事件,在触发事件后向引擎加载事件回调。因此,Node.js 是应用程序中实时数据传输的绝佳选择。
4、Node.js 中的模块
Node.js 的许多功能都包含在软件自带的模块中。这些模块旨在将程序构件分割成易于管理的小块,就像乐高积木一样。有了这些模块,我们只需导入程序所需的模块即可。
例如,下面的代码导入了一个名为 fs
的内置模块。
const fs = require('node:fs')
但在 Node.js 中,我们还可以通过其他方式使用模块。除了内置模块,我们还可以使用其他开发人员构建的模块(或包)。
Node Package Manager(NPM)是一个与 Node.js 配套的软件应用程序。它管理 Node.js 中可用的所有第三方模块。无论何时需要第三方软件包,都可以使用 npm install
命令从 NPM 安装。
要从NPM导入你安装的模块,看起来像这样:
const newModule = require('newModule')
5、展望 Node.js
Node.js 现在拥有一个庞大的开发者社区。它在 GitHub 上有成千上万的贡献者,并被当今一些最大的公司所使用。但是,Node.js 的未来会怎样呢?
Node.js 自 2009 年问世以来发展迅速。它最初用于后端开发,但现在可以做更多的事情。您可以使用 Node.js 开发桌面应用程序、前端网络应用程序、移动应用程序和命令行工具。开发人员将继续在越来越多的应用中使用 Node.js。
Ryan Dahl——Node.js的发明者——在2018年宣布了一个名为Deno的新的JavaScript运行时。他在题为“关于Node.js我后悔的10件事”的演讲中公布了他与人合作创建的运行时。
Deno 是一个 JavaScript 运行时环境,基于 Google Chrome 浏览器的 V8 引擎,但使用 Rust 编写。Deno 不仅是 JavaScript 的运行时环境,也是 TypeScript 的运行时环境。
Ryan Dahl 创建 Deno 是因为他认为自己在 Node.js 的原始蓝图方面做出了一些错误的决定。他希望为 Web 服务器的 JavaScript 运行时环境做出更好的架构决策。这就是 Deno。
但是,Deno 还没有在开发者社区得到大规模采用。它仍然是一项相对较新的技术,需要更多的时间来普及。
此外,积极管理、开发和维护 Node.js 的 OpenJS 基金会一直在修复 Node.js 的一些错误,并提高其最终效率。越来越多的项目建立在 Node.js 架构之上,在可预见的未来,这种情况可能还会继续下去。
总结
在本文中,您已经学到了很多,现在可以自信地回答“Node.js到底是什么?”这个问题。
我们首先回顾了Node.js的历史,然后正确地定义了Node.js。之后,我们详细阐述了Node.js的工作原理,解释了V8引擎、Libuv和事件循环等组件。
之后,我们讨论了 Node.js 和 NPM 中的模块。最后,我们展望了 Node.js 的未来,并得出结论:Node.js 将为更多应用程序提供动力。
如果您想学习如何使用 Node.js 构建应用程序,freeCodeCamp 有一个专门介绍 Node.js 的完整教程播放列表。互联网上有大量学习该技术的资源,未来还会有更多。