其他常用模块
以下是 Node.js 中几个重要内置模块的详细介绍,涵盖事件触发器、定时器、加密、压缩、操作系统信息和实用工具。
一、事件触发器(events)
events 模块是 Node.js 实现「事件驱动」架构的核心,许多内置模块(如 http.Server、stream)都继承自 EventEmitter。
1. 自定义事件与继承 EventEmitter
const EventEmitter = require("events");
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on("event", (arg1, arg2) => {
console.log("事件触发", arg1, arg2);
});
myEmitter.emit("event", "hello", "world");
也可以直接使用 EventEmitter 实例,不必要继承。
2. 内存管理:setMaxListeners
默认情况下,为同一个事件添加超过 10 个监听器会触发警告(防止内存泄漏)。可通过 setMaxListeners 调整限制:
myEmitter.setMaxListeners(20);
console.log(myEmitter.getMaxListeners()); // 20
若要彻底移除警告,可设为 0(不推荐)。
3. 其他常用方法
once(event, listener):只执行一次后自动移除。prependListener:将监听器添加到数组头部。removeListener/off:移除特定监听器。removeAllListeners([event]):移除所有监听器。listenerCount(event):获取监听器数量。eventNames():返回已注册事件名称数组。
4. 错误处理
如果 EventEmitter 实例发生错误且没有监听 'error' 事件,Node.js 会抛出异常并打印堆栈。因此建议始终监听 'error' 事件。
myEmitter.on("error", err => {
console.error("发生错误:", err);
});
二、定时器(timer)
Node.js 的定时器与浏览器类似,但实现上基于 libuv 的事件循环,具有一些差异。
| 方法 | 描述 | 执行时机 | 精度 | 长时间延迟影响 |
|---|---|---|---|---|
setTimeout | 延迟执行一次 | 在 timers 阶段(可能受其他回调阻塞) | 4ms 以内(嵌套调用) | 可能延迟 |
setInterval | 周期性执行 | 每个周期尝试在 timers 阶段执行 | 同上 | 累积偏移 |
setImmediate | 尽快执行一次 | 在 check 阶段(poll 阶段之后) | 较高 | 几乎不受影响 |
process.nextTick | 尽快执行 | 在当前阶段结束后、下个阶段开始前 | 最高 | 会阻塞事件循环 |
重要区别:
setImmediate与setTimeout(fn, 0):在 I/O 循环中,setImmediate总是先执行;在顶层模块中,顺序取决于性能(通常setTimeout可能随机先执行)。process.nextTick优先级最高,会递归导致 I/O 饥饿,官方推荐使用setImmediate或重构。
取消定时器:clearTimeout、clearInterval、clearImmediate。
const timeoutId = setTimeout(() => {}, 1000);
clearTimeout(timeoutId);
注意:setInterval 可能因回调执行时间长而导致积压(下一次调用之前未完成),建议使用递归 setTimeout 实现精确间隔。
三、加密(crypto)
crypto 模块提供加密功能,包含哈希、HMAC、对称/非对称加密及随机数生成。
1. 哈希(createHash)
哈希算法(MD5、SHA-256 等)将任意长度数据转换为固定长度摘要,不可逆。
const crypto = require("crypto");
const hash = crypto.createHash("sha256");
hash.update("some data");
console.log(hash.digest("hex")); // 十六进制字符串
2. HMAC(基于哈希的消息认证码)
HMAC 需要密钥,用于验证消息完整性和真实性。
const hmac = crypto.createHmac("sha256", "secret-key");
hmac.update("message");
console.log(hmac.digest("hex"));
3. 对称加密
使用相同密钥加密和解密,如 AES。
const algorithm = "aes-256-cbc";
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update("plain text", "utf8", "hex");
encrypted += cipher.final("hex");
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(encrypted, "hex", "utf8");
decrypted += decipher.final("utf8");
console.log(decrypted); // 'plain text'
4. 非对称加密(RSA)
使用公钥加密,私钥解密。
const { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", {
modulusLength: 2048,
});
const encrypted = crypto.publicEncrypt(publicKey, Buffer.from("secret"));
const decrypted = crypto.privateDecrypt(privateKey, encrypted);
console.log(decrypted.toString()); // 'secret'
5. 随机数生成
crypto.randomBytes(size):生成安全的伪随机字节。crypto.randomInt(min, max):生成随机整数。
crypto.randomBytes(16, (err, buf) => {
console.log(buf.toString("hex"));
});
四、压缩(zlib)
zlib 模块提供 gzip、deflate、brotli 等压缩算法。
1. 压缩与解压(gzip 示例)
回调风格:
const zlib = require("zlib");
const fs = require("fs");
const gzip = zlib.createGzip();
const inp = fs.createReadStream("input.txt");
const out = fs.createWriteStream("input.txt.gz");
inp.pipe(gzip).pipe(out);
Promise 风格(zlib.promises):
const { promisify } = require("util");
const gzip = promisify(zlib.gzip);
async function compress(data) {
const compressed = await gzip(data);
console.log(compressed);
}
2. 常用方法
zlib.gzip(buf, callback)/gunzipzlib.deflate/inflatezlib.brotliCompress/brotliDecompress(Node.js 11.7+)
3. 内存与性能
压缩和解压是 CPU 密集型操作,建议在流中使用,避免一次性处理大文件。
五、操作系统信息(os)
os 模块提供操作系统级别的系统信息。
| 方法 | 描述 |
|---|---|
os.cpus() | 返回每个 CPU 核心的信息(型号、速度、时间) |
os.totalmem() / os.freemem() | 总内存 / 空闲内存(字节) |
os.networkInterfaces() | 网络接口信息(IPv4/IPv6、MAC 地址等) |
os.loadavg() | 系统负载平均值(1, 5, 15 分钟) |
os.EOL | 操作系统行结束符(\n 或 \r\n) |
os.platform() | 操作系统平台('linux'、'win32'、'darwin') |
os.homedir() | 当前用户的主目录 |
os.uptime() | 系统运行时间(秒) |
示例:获取 CPU 核心数以优化子进程数量
const os = require("os");
const cpus = os.cpus().length;
console.log(`CPU 核心数: ${cpus}`);
六、实用工具(util)
util 模块提供多种实用函数,帮助调试、类型转换和回调 Promise 化。
1. util.promisify
将遵循 Node.js 错误优先回调风格的函数转为返回 Promise 的函数。
const util = require("util");
const fs = require("fs");
const readFile = util.promisify(fs.readFile);
readFile("./file.txt", "utf8")
.then(data => console.log(data))
.catch(err => console.error(err));
2. util.types
提供一系列类型检查方法(比 typeof 或 instanceof 更可靠)。
const { types } = require("util");
console.log(types.isDate(new Date())); // true
console.log(types.isMap(new Map())); // true
console.log(types.isPromise(Promise.resolve())); // true
3. util.inspect
将对象格式化为字符串,用于调试。可通过 depth、colors、showHidden 等选项控制。
const obj = { a: 1, b: { c: 2 } };
console.log(util.inspect(obj, { depth: 1, colors: true }));
Node.js 在内部使用 util.inspect 实现 console.log 的对象展示。
4. util.callbackify
将 async 函数(或返回 Promise 的函数)转换为错误优先的回调风格函数(与 promisify 相反)。
const { callbackify } = require("util");
async function asyncFn() {
return "hello";
}
const callbackFn = callbackify(asyncFn);
callbackFn((err, ret) => {
console.log(ret); // 'hello'
});
5. 其他
util.format(format, [...args]):类似printf的字符串格式化。util.deprecate(fn, msg):标记方法已弃用,调用时会打印警告。
总结
| 模块 | 核心用途 | 常用场景 |
|---|---|---|
events | 实现事件驱动架构 | 自定义事件、继承 EventEmitter |
timer | 调度异步执行 | 延迟、周期性、尽快执行 |
crypto | 加密与安全 | 哈希、HMAC、对称/非对称加密、随机数 |
zlib | 数据压缩 | 文件压缩、HTTP 传输压缩 |
os | 获取系统信息 | 性能调优、资源监控 |
util | 通用工具 | 回调转 Promise、类型检查、调试打印 |
这些模块构成了 Node.js 生态的重要基础,熟练掌握可以大幅提升开发效率和程序健壮性。
相关文章
文件系统
Node.js 的 fs 模块提供了与文件系统交互的 API,几乎涵盖了所有标准文件操作。它支持三种风格的 API:同步、回调式异步 和 Promise 式异步。下面详细介绍这些 API 的选择策略、流式读写、文件监视以及常用操作。
缓冲区
Buffer 是 Node.js 全局对象,用于处理二进制数据流(如文件、网络数据)。在 ES6 引入 TypedArray 之前,Buffer 是 Node.js 处理二进制的主要方式;现在 Buffer 实现了 Uint8Arra…
路径处理
path 模块提供了用于处理和转换文件路径的实用工具。它是 Node.js 核心模块,无需安装即可直接使用。由于不同操作系统(Windows、Linux、macOS)的路径分隔符不同(Windows 使用反斜杠 \,POSIX 使用正…
进程与子进程
Node.js 在单个进程中运行,但通过 process 对象、child_process 模块及 worker_threads 模块提供了对进程的精细控制以及多进程/多线程能力。下面从三个方面展开。
网络编程
Node.js 提供了丰富的内置模块,用于构建网络应用。下面从 HTTP/HTTPS、WebSocket、TCP/UDP 以及 DNS 解析四个方面进行深入介绍。
流
流是 Node.js 中处理有序数据的抽象接口,用于以连续方式异步读取或写入数据。它们特别适合处理大文件、网络通信或任何可能无限产生的数据。Node.js 内置的 stream 模块提供了四种基本流类型,以及用于组合和错误处理的工具函数。