直接跳到内容

node 简介

Node.js 是一个开源的、跨平台的 JavaScript 运行时环境,基于 Chrome 的 V8 JavaScript 引擎构建。它由 Ryan Dahl 于 2009 年创建,旨在让开发者使用 JavaScript 编写高性能的服务器端应用。Node.js 打破了 JavaScript 仅限浏览器运行的局限,通过事件驱动和非阻塞 I/O 模型,实现了高并发处理能力,特别适合构建实时应用、API 服务和微服务架构。

事件驱动架构

Node.js 的核心是事件驱动架构,它通过事件发射器和监听器处理异步操作。当特定事件发生时 (如网络请求完成),事件发射器会触发事件,而注册的监听器则执行相应回调函数。这种模型避免了多线程编程的复杂性,同时提高了资源利用率。

示意图:

事件流:
  事件发射器 --触发--> 事件监听器
  例如: 
    server.on('request', (req, res) => {
      // 处理请求
    });

事件驱动使得应用能够以非阻塞方式响应多个输入,例如在 Web 服务器中,一个请求不会阻塞其他请求的处理。

非阻塞 I/O

Node.js 采用非阻塞 I/O 模型,在执行输入输出操作 (如文件读写或网络调用) 时,不会等待操作完成,而是立即返回并继续执行其他任务。当 I/O 操作完成后,通过回调函数处理结果。这显著提升了吞吐量,尤其在高 I/O 负载场景下。

示意图:

同步 I/O:
  请求 --> [阻塞等待] --> 响应
  例如: 读取文件时,线程被挂起,直到数据返回。

非阻塞 I/O:
  请求 --> [立即返回] --> 执行其他任务 --> 回调处理响应
  例如: 
    fs.readFile('file.txt', (err, data) => {
      // 文件读取完成后执行
    });

这种机制通过底层库 libuv 实现,它利用操作系统特性 (如 epoll 或 kqueue) 来管理异步操作,确保单线程也能高效处理并发。

单线程事件循环

尽管 Node.js 运行在单线程中,但它通过事件循环机制实现并发。事件循环不断检查事件队列,依次执行就绪的回调函数,同时将耗时的 I/O 操作委托给系统线程池 (通过 libuv 管理)。这避免了线程创建和上下文切换的开销,但要求开发者避免 CPU 密集型任务阻塞主线程。

示意图:

事件循环流程:
  开始 --> 检查计时器 --> 检查 I/O 回调 --> 检查闲置句柄 --> 循环
  例如:
    while (有事件) {
      处理下一个事件;
    }

如果主线程被阻塞,事件循环会停滞,导致应用无响应。因此,Node.js 推荐将 CPU 密集型任务分流到工作线程或子进程。

异步编程

Node.js 强调异步编程模式,最初通过回调函数实现,但容易引发“回调地狱”。后续引入了 Promise 和 async/await 语法,使代码更易读和维护。异步操作允许任务在后台执行,主线程继续处理其他事件。

示意图:

回调示例:
  fs.readFile('data.json', (err, data) => {
    if (err) throw err;
    console.log(data);
  });

Promise 示例:
  fetch('https://api.example.com/data')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error(error));

async/await 示例:
  async function getData() {
    try {
      const data = await fetchData();
      console.log(data);
    } catch (error) {
      console.error(error);
    }
  }

这些模式通过微任务队列和事件循环协调,确保异步操作按顺序执行,而不会阻塞主线程。

NPM 生态系统

Node.js 集成了 NPM (Node Package Manager),这是全球最大的软件注册表,提供超过百万个可重用模块。NPM 允许开发者轻松安装、管理和共享代码包,加速开发流程。例如,使用 npm install express 可以快速添加 Web 框架。

示意图:

NPM 工作流:
  项目初始化 --> 安装依赖 --> 使用模块
  例如:
    npm init -y
    npm install lodash
    const _ = require('lodash');

NPM 还支持脚本管理和版本控制,使项目依赖管理变得简单可靠。

模块系统

Node.js 使用 CommonJS 模块系统,允许将代码拆分为可重用的模块。每个文件被视为一个模块,通过 require 导入和 module.exports 导出功能。这促进了代码组织和维护。

示意图:

模块示例:
  // math.js
  module.exports = {
    add: (a, b) => a + b
  };

  // app.js
  const math = require('./math.js');
  console.log(math.add(2, 3)); // 输出 5

ES 模块也得到支持,可通过 importexport 语法使用,适应现代 JavaScript 标准。

性能特点

Node.js 的性能优势源于 V8 引擎的即时编译 (JIT) 优化和事件驱动设计。V8 将 JavaScript 代码编译为机器码,提升执行速度,而事件循环减少了资源争用。在高并发场景下,Node.js 能够处理数千个同时连接,延迟较低。

示意图:

请求处理对比:
  传统多线程:
    请求1 --> [线程1] --> 响应
    请求2 --> [线程2] --> 响应
    资源开销高,上下文切换频繁

  Node.js 单线程:
    请求1 --> [事件循环] --> 回调
    请求2 --> [事件循环] --> 回调
    资源利用率高,适合 I/O 密集型任务

然而,对于 CPU 密集型应用 (如图像处理),Node.js 可能性能不佳,建议使用工作线程或外部服务。

应用场景

Node.js 广泛应用于实时应用、RESTful API、微服务和命令行工具。例如,WebSocket 服务器可以处理实时聊天,而 Express 框架简化了 Web 服务开发。其轻量级特性也适合云原生和容器化部署。

示意图:

典型应用:
  实时应用: 聊天室 --WebSocket--> 广播消息
  API 服务: 客户端 --HTTP请求--> Node.js 处理 --> 数据库
  工具链: 构建脚本 --文件操作--> 输出结果
node 简介已经加载完毕