node.js 实战——(概念以及Buffer 知识点学习)

概念

node.js是一个开源的、跨平台的javascript运行环境;它可以开发服务器应用,可以开发工具类应用(webpack、vite、Babel),也可以开发桌面端应用(vscode、Figma、Postman)
node electron vscode figma postman

注意:

1)node.js 中不能使用BOM(Brower Object Model)和 DOM (Document Object Model)的API

  1. node.js 中的顶级对象为global ,也可以用globalThis访问顶级对象

node的特点

异步I/O

I/O 是 Input/Output 的缩写,指的是程序与外部进行"交流"的过程,比如:

• 从硬盘读取文件

• 向数据库写数据

• 网络请求发送/接收数据

  • 同步I/O
    与异步I/O对应的是同步 I/O,那什么是同步I/O?同步I/O就是等结果才干下一步。
javascript 复制代码
const fs = require('fs')

let data =fs.readFileSync("./file/2.mov");
console.log(data); //需要等待将文件读取完毕之后,才打印出这个data
  • 异步I/O
    异步 I/O是先安排任务,等会儿回来拿结果
javascript 复制代码
const fs = require('fs')
fs.readFile("./fileSystem.txt", "utf8", (err, data) => {
    if (err) {
        console.log(err)
    }
    console.log(data)
})
console.log("read file");

事件与回调函数

回调函数

回调函数是一个"等你处理完再叫我"的函数

事件

系统某个"动作"发生了,比如"文件读完了"、"请求完成了",它就会触发一个事件。

单线程

Node保持了JavaScript在浏览器中单线程的特点。

  • 好处
    单线程的最大好处是不用像多线程编程那样处处在意状态的同步问题,这里没有死锁的存在,也没有线程上下文交换所带来的性能上的开销。
  • 缺点
    无法利用多核CPU

针对缺点的解决方案:

1、使用 cluster 模块(内置)

• 启动多个 Node 进程,每个进程一个 CPU 核心。

• 主进程负责分发请求,子进程负责处理。

javascript 复制代码
const cluster = require('cluster');
const os = require('os');

if (cluster.isMaster) {
  const cpus = os.cpus().length;
  for (let i = 0; i < cpus; i++) {
 cluster.fork(); // 启动多个子进程
  }
} else {
  // 各个子进程独立跑服务
  require('./app'); 
}

2、使用 PM2(生产级进程管理器)

• 简化多进程管理,支持 cluster 模式,崩溃自动重启。

powershell 复制代码
pm2 start app.js -i max  # 根据 CPU 数自动 fork

错误回英气整个应用推出,应用的健壮性值得考验

解决方案

1、错误处理策略:全面 try/catch + 全局监听

2、使用中间件捕获错误(在框架中如 Express/NestJS)

3、 使用 PM2 进行守护重启

大量计算占用CPU导致无法继续调用异步I/O

解决方案

1、Worker Threads(Node 10.5+ 支持)

• Node.js 原生的多线程模块,适合重计算任务。

javascript 复制代码
const { Worker } = require('worker_threads');
const worker = new Worker('./heavy-task.js'); // 把大计算扔到 worker 去干
worker.on('message', result => {
console.log('计算结果:', result);
});

2、把计算任务 offload 到别的服务(如 Python)

• 比如图像处理、机器学习等,用子进程或远程服务来做

3、使用 WebAssembly

• 某些计算密集任务可以用 Rust/C 编译成 WebAssembly,在 Node 里跑得飞快且不阻塞。

跨平台

Buffer缓冲区

buffer 类似于Array的对象,用于表示固定长度的字节序列,用于处理二进制数据

中文在utf-8中占三个字节

Buffer 是一个典型的javascript与c++结合的模块,他将性能相关部分用C++实现,将非性能相关的部分用javascript实现。
C++内建模块 node_buffer javascript核心模块 Buffer/ slowBuffer

特点

  1. Buffer 大小固定且无法调整
  2. Buffer性能较好,可以直接对计算机内存进行操作
  3. 每个元素的大小为1字节(8位)

创建Buffer

alloc

javascript 复制代码
let buf =Buffer.alloc(10);

allocUnsafe

javascript 复制代码
let buf = Buffer.allocUnsafe(10);

alloc 和 allocUnsafe 的区别:

  • alloc 在创建的时候,会将申请到的内存数据清零
  • allocUnsafe创建时,可能包含旧的内存数据,但正因为保留了之前的数据,速度比alloc快

from

将字符串/数组转换成buffer,每一个字符会先转换成unicode对应的,然后再转二进制

javascript 复制代码
let buf = Buffer.from("你好");

溢出

Buffer 每个元素的大小为1字节,也就是8位,能表示的最大值为 255 即11111111;那么当超过255之后,程序会如何处理呢。

这里并没有输出361,而是105 ,这是因为361 的二进制是 0001 0110 1001 ;当超过255之后,会舍弃高位,即舍去了高位的0001 ,就剩下0110 1001 (十进制:105)

Buffer与字符串的转换

可以直接借助toString方法将Buffer转位字符串

字符串转Buffer

主要是通过构造函数完成的

javascript 复制代码
new Buffer(str,[encoding])

Buffer 内存分配

Buffer对象的内存分配不是在V8的堆内存中,而是在node的C++层面实现内存的申请。

为了高效地使用申请来的内存,node采用的slab分配机制。slab简单来说,就是一块申请好的固定大小的内存区域。

应用场景

在文件I/O 和 网络I/O 中运用广泛

相关推荐
brien941 分钟前
为什么模型标称 1M,Google Antigravity 聊到 256K 却突然失忆?我们给它做了个原生行内监控圆环
前端
修炼的dance1 小时前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M1 小时前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写1 小时前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李1 小时前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易1 小时前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
风骏时光牛马2 小时前
前沿视界
前端
kyriewen2 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员
陈随易2 小时前
3000 万人在用的翻译插件,重写一遍就是一门生意
前端·后端·程序员
IT_陈寒2 小时前
Vue的这个响应式陷阱,差点让我加班到天亮
前端·人工智能·后端