Node.js究竟是什么?初学者指南

如果你正在考虑使用JavaScript进行后端开发,你会听到“Node.js”这个术语。Node通常与开发功能强大的web服务器联系在一起。

但 Node.js 究竟是什么?它是和 Angular 一样的 JavaScript 框架吗?它是一种编程语言吗?它是 JavaScript 库吗?它是一组技术的总称吗?或者它只是 JavaScript 的另一个词?

在本文中,我们将深入了解 Node.js 的世界,了解它是什么、为什么创建它以及它的用途。这不是一个基于项目的教程——它旨在向初学者介绍 Node 及其工作原理。

以下是我们将讨论的主题:

  1. Node.js的历史

  2. 什么是Node.js?

  3. Node.js是如何工作的?

  4. Node.js 中的模块

  5. 展望未来的 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: 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 的完整教程播放列表。互联网上有大量学习该技术的资源,未来还会有更多。


原文:https://www.freecodecamp.org/news/what-exactly-is-node-guide-for-beginners/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/23689.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中国中医中药元宇宙 中药材价格缘何“狂飙”

◇相比去年同期,有超200个常规品种涨幅高于50%,25个常用大宗药材涨幅超200%,个别品种甚至涨价4至9倍 ◇在中药材价格普遍高涨的情况下,部分市场仓库库存数量也较多,出现囤积居奇倾向 ◇“不少游资和热钱涌入中药材市场…

Spring Boot + Vue3前后端分离实战wiki知识库系统<十一>--文档管理功能开发三

文档内容的显示: 在上一次Spring Boot Vue3前后端分离实战wiki知识库系统<十>--文档管理功能开发二文档管理模块还差文档的显示木有完成,所以接下来先将这块模块给收尾了。 增加单独获取内容的接口: 概述&#xff…

设计模式、Java8新特性实战 - List<T> 抽象统计组件

一、背景 在日常写代码的过程中,针对List集合,统计里面的某个属性,是经常的事情,针对List的某个属性的统计,我们目前大部分时候的代码都是这样写,每统计一个变量,就要定义一个值,且…

ATTCK实战系列-红队评估 (红日靶场3)Vulnstack三层网络域渗透靶场

文章目录 环境配置靶场介绍靶场设置 外网渗透信息收集端口扫描目录扫描 漏洞发现与利用获取ssh账号密码,登录centos 提权 内网渗透建立代理内网信息收集smb暴破,获取本地管理员密码 横向移动使用psexec模块上线msf 环境配置 靶场介绍 靶场地址 http:/…

剑指Offer 20.表示数值的字符串

20.表示数值的字符串 题目 官方地址 代码(正则表达式) public boolean isNumeric (String str) {if (str null || str.length() 0)return false;return new String(str).matches("[-]?\\d*(\\.\\d)?([eE][-]?\\d)?"); }在给定的代码…

PCIE链路信息

目录 简介: 目的: 详情: 简介: PCIe有很多寄存器,也有很多控制,包括链路状态信息,上一节我们讲到了PCie的链路训练,这节文章将继续学习PCIe相关知识。 目的: 从设计…

【Python从小白到高手】---函数基础

个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【Python小白从入门到精通】🎈 本专栏旨在分享学习Python的一点学习心得,欢迎大家在评论区讨论💌 目录…

iPhone 6透明屏是什么?原理、特点、优势

iPhone 6透明屏是一种特殊的屏幕技术,它能够使手机屏幕变得透明,让用户能够透过屏幕看到手机背后的物体。 这种技术在科幻电影中经常出现,给人一种未来科技的感觉。下面将介绍iPhone 6透明屏的原理、特点以及可能的应用。 iPhone 6透明屏的原…

本地 shell无法连接centos 7 ?

1、首先检查是否安装ssh服务; yum list installed | grep openssh-server# 没有安装尝试安装下 yum install openssh-server 2、检查ssh服务是否开启 systemctl status sshd.service# 未开启,开启下 systemctl start sshd.service # 将sshd 服务添…

socker套接字

1.打印错误信息 2.socketaddr_in结构体 结构体: (部分库代码) (宏中的##) 3.manual TCP: SOCK_STREAM : 提供有序地,可靠的,全双工的,基于连接的流式服务 UDP: 面向数据报

406 · 和大于S的最小子数组

链接:LintCode 炼码 - ChatGPT!更高效的学习体验! 题解:同向双指针 九章算法 - 帮助更多程序员找到好工作,硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧 class Solution { public:/*** param nums: an array …

【maven】构建项目前clean和不clean的区别

其实很简单,但是百度搜了一下,还是没人能简单说明白。 搬用之前做C项目时总结结论: 所以自己在IDE里一遍遍测试程序能否跑通的时候,不需要clean,因为反正还要改嘛。 但是这个项目测试好了,你要打成jar包给…

element-tree-line el-tree 添加结构线 添加虚线

概览:给element组件添加上虚线,通过使用插件element-tree-line 参考连接: 参考别人的博客 安装插件: # npm npm install element-tree-line -S # yarn yarn add element-tree-line -S main.js全局注册引入插件: imp…

Python批量查字典和爬取双语例句

最近,有网友反映,我的批量查字典工具换到其它的网站就不好用了。对此,我想说的是,互联网包罗万象,网站的各种设置也有所不同,并不是所有的在线字典都可以用Python爬取的。事实上,很多网站为了防…

Linux文本三剑客---grep、sed、awk

目录标题 1、grep1.1 命令格式1.2命令功能1.3命令参数1.4grep实战演练 2、sed2.1 认识sed2.2命令格式2.3常用选项options2.4地址定界2.5 编辑命令command2.6用法演示2.6.1常用选项options演示2.6.2地址界定演示2.6.3编辑命令command演示 3、awk3.1认识awk3.2常用命令选项3.3awk…

向表中随机插入字符串数据

已知表 向该表中插入指定次数的随机字符串: 代码如下: DROP PROCEDURE sc //CREATE PROCEDURE sc(num INT) BEGIN DECLARE str VARCHAR(26) DEFAULT "abcdefghijklmnopqrstuvwxyz"; DECLARE cnt INT DEFAULT 0; DECLARE startIndex INT DEFAULT 1; DE…

msvcp120.dll丢失的解决方法(亲测可修复方的法)

在运行某些软件的时候,计算机提示msvcp120.dll丢失,无法打开运行软件。在第一次遇到这个问题的时候,相信很多人都不知道是怎么回事。下面小编把msvcp120.dll是什么以及如何解决这个问题的详细方法给大家科普一下。 问题描述: 在使…

Ubuntu安装MySQL 8.0与Navicat

目录 Ubuntu安装MySQL 8.0 1、更新软件包列表 2、安装 MySQL 8.0 3、启动 MySQL 服务 5、确保MySQL服务器正在运行 5、root 用户的密码 6、登录MySQL,输入mysql密码 7、MySQL默认位置 Ubuntu安装Navicat 1、下载 Navicat 2、额外的软件包 3、执行命令 U…

周末在家值班,解决几个月前遗忘的Bug

问题: 周末被迫在家值班,无聊之际打开尘封已久的Bug清单,发现有Bug拖了几个月还没解决… 场景是这样子的,有个功能是拿Redis缓存热点数据进行展示,暂且称它为功能A,有个另外的功能B,它会去更新缓…

lifecycleScope Unresolved reference

描述 导入了lifecycle.lifecycleScope,但是在activity中使用lifecycleScope报错出现Unresolved reference找不到引用。 导包 import androidx.lifecycle.lifecycleScope使用 lifecycleScope.launch(Dispatchers.IO) {...}错误 方案 代码中的activity继承Activ…