前端都应该了解的 NodeJs 知识及原理浅析

本文详细介绍了Node.js的基础,包括安装、npm包管理工具,以及Node.js的核心模块、底层依赖如V8引擎、libuv等。深入探讨了事件循环模型,详细解析了各个阶段,如timers、poll和check,以及Buffer的使用,包括内存管理和字符编码。文章还对比了Node.js与其他JS解析引擎,如QuickJS和Deno的特点,强调了全局对象和全局变量的区别,特别关注了Buffer在处理二进制数据中的作用。最后,讨论了事件循环和Stream的概念,展示了如何在实际应用中利用这些机制。
摘要由CSDN通过智能技术生成

node.js 初探

Node.js 是一个 JS 的服务端运行环境,简单的来说,它是在 JS 语言规范的基础上,封装了一些服务端的运行时对象,让我们能够简单实现非常多的业务功能。

如果我们只使用 JS 的话,实际上只是能进行一些简单的逻辑运算。node.js 就是基于 JS 语法增加与操作系统之间的交互。

node.js 的安装

我们可以使用多种方式来安装 node.js,node.js 本质上也是一种软件,我们可以使用直接下载二进制安装文件安装,通过系统包管理进行安装或者通过源码自行编译均可。

一般来讲,对于个人开发的电脑,我们推荐直接通过 node.js 官网的二进制安装文件来安装。对于打包上线的一些 node.js 环境,也可以通过二进制编译的形式来安装。

安装成功之后,我们的 node 命令就会自动加入我们的系统环境变量 path 中,我们就能直接在全局使用 node 命令访问到我们刚才安装的 node 可执行命令行工具。

node.js 版本切换在个人电脑上,我们可以安装一些工具,对 node.js 版本进行切换,例如 nvmn

nvm 的全称就是 node version manager,意思就是能够管理 node 版本的一个工具,它提供了一种直接通过 shell 执行的方式来进行安装。简单来说,就是通过将多个 node 版本安装在指定路径,然后通过 nvm 命令切换时,就会切换我们环境变量中 node 命令指定的实际执行的软件路径。

安装成功之后,我们就能在当前的操作系统中使用多个 node.js 版本。

包管理工具 npm

curl -o- https://raw.githubusercontent.com/nvm- sh/nvm/v0.35.3/install.sh | bash

我们对 npm 应该都比较熟悉了,它是 node.js 内置的一款工具,目的在于安装和发布符合 node.js 标准的模块,从而实现社区共建的目的繁荣整个社区。

npx 是 npm@5 之后新增的一个命令,它使得我们可以在不安装模块到当前环境的前提下,使用一些 cli 功能。

例如 npx create-react-app some-repo

node.js 的底层依赖

node.js 的主要依赖子模块有以下内容:

V8 引擎

主要是 JS 语法的解析,有了它才能识别 JS 语法\

libuv

c 语言实现的一个高性能异步非阻塞 IO 库,用来实现 node.js 的事件循环

http-parser/llhttp

底层处理 http 请求,处理报文, 解析请求包等内容

openssl

处理加密算法,各种框架运用广泛

zlib

处理压缩等内容 node.js 常⻅内置模块

主要模块

node.js 中最主要的内容,就是实现了一套 CommonJS 的模块化规范,以及内置了一些常⻅的模块。

fs:

文件系统,能够读取写入当前安装系统环境中硬 盘的数据\

path:

路径系统,能够处理路径之间的问题

crypto:

加密相关模块,能够以标准的加密方式对我 们的内容进行加解密

dns:

处理 dns 相关内容,例如我们可以设置 dns 服 务器等等\

http:

设置一个 http 服务器,发送 http 请求,监听 响应等等

readline:

读取 stdin 的一行内容,可以读取、增加、 删除我们命令行中的内容\

os:

操作系统层面的一些 api,例如告诉你当前系统类 型及一些参数

vm:

一个专⻔处理沙箱的虚拟机模块,底层主要来调 用 v8 相关 api 进行代码解析。

V8 引擎:

github.com/v8/v8 chromium.googlesource.com/v8/v8.git

引擎只是解析层面,具体的上层还有许多具体环境的封装。

Debug & 内存泄漏

对于浏览器的 JS 代码来说,我们可以通过断点进行分步调试,每一步打印当前上下文中的变量结果,来定位具体问题出现在哪一步。

我们可以借助 VSCode 或者自行打断点的形式,来进行分步 node.js 调试。

对于 JS 内存泄漏,我们也可以使用同样的道理,借助工具,打印每次的内存快照,对比得出代码中的问题。

另一种 JS 解析引擎 quickjs

quickjs 是一个 JS 的解析引擎,轻量代码量也不大,与之功能类似的就是 V8 引擎。

他最大的特点就是,非常非常轻量,这点从源码中也能体现,事实上并没有太多的代码,它的主要特点和优势:

1.轻量而且易于嵌入: 只需几个C文件,没有外部依赖,一个x86下的简单的“hello world”程序只要180 KiB2.具有极低启动时间的快速解释器: 在一台单核的台式PC上,大约在100秒内运行ECMAScript 测试套件156000次的运行时实例完整生命周期在不到300微秒的时间内完成。3.几乎完整实现ES2019支持,包括: 模块,异步生成器和和完整Annex B(MPEG-2 transport stream format格式)支持 (传统的Web兼容性)。许多ES2020中带来的特性也依然会被支持。 通过100%的ECMAScript Test Suite测试。 可以将Javascript源编译为没有外部依赖的可执行文件。另一类 JS 运行时服务端环境 deno

deno 是一类类似于 node.js 的 JS 运行时环境,同时它也是由 node.js 之父一手打造出来的,他和 node.js 比有什么区别呢?

相同点:
  • deno 也是基于 V8 ,上层封装一些系统级别的调用我们的 deno 应用也可以使用 JS 开发
不同点:
  • deno 基于 rust 和 typescript 开发一些上层模块,所以我们可以直接在 deno 应用中书写 ts* deno 支持从 url 加载模块,同时支持 top level await 等特性全局对象解析
    ======

JavaScript 中有一个特殊的对象,称为全局对象(Global Object),它及其所有属性都可以在程序的任何地方访问,即全局变量。

在浏览器 JavaScript 中,通常 window 是全局对象, 而 Node.js 中的全局对象是 global,所有全局变量(除了 global 本身以外)都是 global 对象的属性。

在 Node.js 我们可以直接访问到 global 的属性,而不需要在应用中包含它。

全局对象和全局变量

global 最根本的作用是作为全局变量的宿主。按照 ECMAScript 的定义,满足以下条 件的变量是全局变量:

在最外层定义的变量; 全局对象的属性; 隐式定义的变量(未定义直接赋值的变量)。 当你定义一个全局变量时,这个变量同时也会成为全局对象的属性,反之亦然。需要注 意的是,在 Node.js 中你不可能在最外层定义变量,因为所有用户代码都是属于当前模块的, 而模块本身不是最外层上下文。

注意: 永远使用 var 定义变量以避免引入全局变量,因为全局变量会污染 命名空间,提高代码的耦合风险。

__filename

__filename 表示当前正在执行的脚本的文件名。它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同。 如果在模块中,返回的值是模块文件的路径。

console.log( __filename ); 

__dirname

__dirname 表示当前执行脚本所在的目录。

console.log( __dirname ); 

setTimeout(cb, ms)

setTimeout(cb, ms) 全局函数在指定的毫秒(ms)数后执行指定函数(cb)。:setTimeout() 只执行一次指定函数。

返回一个代表定时器的句柄值。

function printHello(){ console.log( "Hello, World!");
}
// 两秒后执行以上函数
setTimeout(printHello, 2000); 

clearTimeout、setInterval、clearInterval、console 在js中比较常见,故不做展开。

process

process 是一个全局变量,即 global 对象的属性。

它用于描述当前Node.js 进程状态的对象,提供了一个与操作系统的简单接口。通常在你写本地命令行程序的时候,少不了要 和它打交道。下面将会介绍 process 对象的一些最常用的成员方法。

1.exit 当进程准备退出时触发。2.beforeExit 当 node 清空事件循环,并且没有其他安排时触发这个事件。通常来说,当没有进程安排时 node 退出,但是 ‘beforeExit’ 的监听器可以异步调用,这样 node 就会继续执行。3.uncaughtException 当一个异常冒泡回到事件循环,触发这个事件。如果给异常添加了监视器,默认的操作(打印堆栈跟踪信息并退出)就不会发生。4.Signal 事件 当进程接收到信号时就触发。信号列表详见标准的 POSIX 信号名,如 SIGINT、SIGUSR1 等。```
process.on(‘exit’, function(code) {// 以下代码永远不会执行setTimeout(function() {console.log(“该代码不会执行”);}, 0); console.log(‘退出码为:’, code);
});
console.log(“程序执行结束”);


### 退出的状态码

1.Uncaught Fatal Exception 有未捕获异常,并且没有被域或 uncaughtException 处理函数处理。2.Internal JavaScript Parse Error JavaScript的源码启动 Node 进程时引起解析错误。非常罕见,仅会在开发 Node 时才会有。3.Internal JavaScript Evaluation Failure JavaScript 的源码启动 Node 进程,评估时返回函数失败。非常罕见,仅会在开发 Node 时才会有。4.Fatal Error V8 里致命的不可恢复的错误。通常会打印到 stderr ,内容为: FATAL ERROR5.Non-function Internal Exception Handler 未捕获异常,内部异常处理函数不知为何设置为on-function,并且不能被调用。6.Internal Exception Handler Run-Time Failure 未捕获的异常, 并且异常处理函数处理时自己抛出了异常。例如,如果 process.on(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值