Loading... 下面是一份聚焦 Node.js 进程与线程机制以及 fs 模块要点的学习笔记,结合最新 LTS 版本(v20+)特性,涵盖原理、代码示例与分析对照表,方便快速掌握与落地。⚙️ --- ## 一、Node.js 进程与线程机制核心 Node.js 基于 **事件驱动 + 非阻塞 I/O** 架构,采用 **单主线程 + 多辅助线程** 模型: * **主线程(Event Loop)**:负责 JavaScript 执行与事件调度。 * **线程池(libuv)**:处理文件 I/O、DNS 查询、加解密、压缩等耗时任务(默认 4 线程,可调 `UV_THREADPOOL_SIZE`)。 * **子进程(child\_process)**:用于多核 CPU 利用或运行独立任务。 * **Worker Threads**:在同一进程中开辟多 JS 线程,适合 CPU 密集型计算。 --- ### 1.1 机制对照表 | 功能 | 主线程 | 线程池 | 子进程 | Worker Threads | | -------- | --------- | -------------------- | -------------------- | ------------------------- | | JS 执行 | ✅ | ❌ | ✅(独立实例) | ✅(共享内存) | | I/O | 调度 | 执行 | 独立 | 调度/执行 | | 多核利用 | ❌ | 部分(I/O) | ✅ | ✅ | | 开销 | 低 | 中 | 高(进程间通信 IPC) | 中低(共享内存/消息通道) | | 典型场景 | HTTP 服务 | 文件读写、大文件压缩 | 外部命令、独立任务 | 图像处理、复杂计算 | --- ### 1.2 工作流程(Mermaid) ```mermaid flowchart LR A[JS 主线程] -->|发起 I/O 请求| B[libuv 线程池] B -->|完成回调| A A -->|CPU 密集| C[Worker Thread] A -->|独立任务| D[Child Process] ``` --- ### 1.3 示例:Worker Threads 处理 CPU 密集任务 ```js // main.js const { Worker } = require('worker_threads'); function runService(workerData) { return new Promise((resolve, reject) => { const worker = new Worker('./worker.js', { workerData }); worker.on('message', resolve); worker.on('error', reject); worker.on('exit', code => { if (code !== 0) reject(new Error(`退出码: ${code}`)); }); }); } runService({ num: 40 }).then(res => console.log('结果:', res)); ``` * **解释**:`Worker` 在同进程新线程执行 `worker.js`,通过 `message` 回传结果,避免阻塞主线程。 ```js // worker.js const { workerData, parentPort } = require('worker_threads'); function fib(n) { return n < 2 ? 1 : fib(n - 1) + fib(n - 2); } parentPort.postMessage(fib(workerData.num)); ``` * **解释**:耗时的递归运算在独立线程运行,主线程继续处理 I/O。 --- ## 二、fs 模块要点 Node.js `fs` 模块支持**同步**与**异步**两种 API,后者优先推荐(非阻塞)。 --- ### 2.1 常用模式对比 | API 风格 | 特点 | 优势 | 注意事项 | | ----------------------------------- | ---------------- | -------------- | ------------------------- | | 同步(`fs.readFileSync`) | 阻塞 Event Loop | 逻辑简单 | 仅适合启动阶段或脚本 | | 回调式(`fs.readFile`) | 异步回调 | 传统、广泛兼容 | 回调地狱风险 | | Promise(`fs.promises.readFile`) | async/await 支持 | 可读性强 | Node.js 10+ 支持 | | 流式(`fs.createReadStream`) | 按块处理 | 适合大文件 | 注意 backpressure(背压) | --- ### 2.2 示例:Promise + 异步文件读写 ```js const fs = require('fs/promises'); async function copyFile(src, dest) { try { const data = await fs.readFile(src, 'utf-8'); await fs.writeFile(dest, data); console.log('✅ 文件复制完成'); } catch (err) { console.error('❌ 发生错误:', err); } } copyFile('./input.txt', './output.txt'); ``` * **解释**:使用 `fs/promises` 模块直接返回 Promise,可配合 `async/await` 写出同步风格代码,同时保持非阻塞。 --- ### 2.3 示例:流式读取大文件 ```js const fs = require('fs'); const readStream = fs.createReadStream('./bigfile.log', { encoding: 'utf-8' }); readStream.on('data', chunk => { console.log(`📦 接收 ${chunk.length} 字节`); }); readStream.on('end', () => console.log('文件读取完成')); ``` * **解释**:`createReadStream` 边读边处理,减少内存占用,尤其适合 GB 级文件。 --- ## 三、优化与实践建议 1. **CPU 密集型任务**:用 Worker Threads 或 子进程,避免阻塞主线程。 2. **I/O 密集型任务**:利用异步 API + 线程池并行,必要时调大 `UV_THREADPOOL_SIZE`。 3. **文件操作**:大文件用**流式 API**,小文件可直接 Promise API。 4. **跨进程通信**:多进程可用 IPC 管道(`process.send`)、共享内存(`SharedArrayBuffer`)。 --- 如果你愿意,我可以帮你把 **Node.js 进程-线程模型 + fs 操作** 画成一张 **“完整运行架构思维导图”**,一页就能看完全部知识点。这样可以把原理、API、性能优化全部整合在一起。 你需要我直接画出来吗? 最后修改:2025 年 08 月 27 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏