一、Node.js 背景介绍
1.1 Node.js 是什么?
Node.js 是一个基于 Chrome V8 JavaScript 引擎 的 JavaScript 运行时环境,它让 JavaScript 不再局限于浏览器环境,而是可以运行在服务器端、命令行甚至物联网设备上。
核心特点:
- 基于 V8 引擎:Google 开发的 JavaScript 引擎,执行 JavaScript 代码速度极快
- 服务器端 JavaScript:首次让 JavaScript 可以脱离浏览器运行在服务端
- 事件驱动:采用事件驱动架构处理高并发
- 非阻塞 I/O:异步处理输入输出,不阻塞程序执行
- 单线程但高效:通过事件循环机制处理并发
1.2 Node.js 的诞生与发展
2009年5月:由 Ryan Dahl 开发并首次发布
- Ryan Dahl 原本是一名 C++ 开发者,致力于解决高并发网络服务器问题
- 他发现传统的服务器模型(如 Apache)在处理大量并发连接时效率低下
- 受到 EventMachine(Ruby)和 Twisted(Python)的启发,但希望找到更好的解决方案
关键技术决策:
- 选择 V8 引擎 作为 JavaScript 执行引擎
- 采用 事件驱动、非阻塞 I/O 模型
- 设计 单线程 架构但通过事件循环处理高并发
重要里程碑:
- 2009年11月 & 2010年4月:在 JS Conf 大会上展示,引起开发者社区关注
- 2010年底:获得云计算服务商 Joyent 资助,创始人 Ryan Dahl 加入 Joyent 专职负责 Node 发展
- 2011年7月:在 微软 支持下发布 Windows 版本
- 2016年:经历 leftpad 事件后,Yarn 包管理器诞生
- 2021年:发布 Node.js 17 版本
- 2024年12月:持续更新维护,稳定版本广泛应用于生产环境
1.3 为什么需要 Node.js?
传统服务器模型的痛点:
- 每个连接需要一个独立的线程,资源消耗大
- 阻塞 I/O 导致性能瓶颈
- 处理高并发连接时效率低下
Node.js 的解决方案:
- 单线程 + 事件循环:避免了多线程的上下文切换开销
- 非阻塞 I/O:I/O 操作不会阻塞程序执行
- 统一语言:前后端都使用 JavaScript,降低开发成本
- 丰富的生态系统:npm 拥有世界上最大的开源库集合
1.4 Node.js 的应用场景
I/O 密集型应用(最佳选择):
- Web 服务器和 API 服务:轻量级、高并发的 HTTP 服务
- 实时应用:聊天应用、在线游戏、协作工具
- 代理服务器:API 网关、请求转发、负载均衡
- 流媒体服务器:视频/音频流处理
工具和脚本:
- 构建工具:Webpack、Gulp、Grunt 等前端构建工具
- 自动化脚本:文件处理、数据转换、系统管理任务
- 开发工具:本地开发服务器、热重载工具
其他领域:
- 桌面应用:使用 Electron 框架开发跨平台桌面应用
- 物联网 (IoT):设备控制和数据采集
- 移动应用后端:为移动应用提供 API 服务
二、Node.js 核心特性详解
2.1 V8 JavaScript 引擎
什么是 V8 引擎?
- Google 开发的开源 JavaScript 引擎
- 用于 Chrome 浏览器,执行 JavaScript 代码
- 采用即时编译 (JIT) 技术,将 JavaScript 代码直接编译为机器码
V8 在 Node.js 中的优势:
- 高性能:JavaScript 代码执行速度接近原生代码
- 持续优化:V8 团队不断改进性能和内存管理
- 现代 JavaScript 支持:支持 ES6+ 的所有新特性
2.2 事件驱动和非阻塞 I/O
事件驱动模型:
// 典型的事件监听模式
const EventEmitter = require('events');
const emitter = new EventEmitter();
emitter.on('事件名', (数据) => {
console.log('收到事件:', 数据);
});
// 触发事件
emitter.emit('事件名', '一些数据');
非阻塞 I/O 示例:
// 传统阻塞方式(伪代码)
const data = fs.readFileSync('file.txt'); // 阻塞,直到文件读取完成
console.log(data);
// Node.js 非阻塞方式
fs.readFile('file.txt', (err, data) => {
// 文件读取完成后回调这个函数
if (err) throw err;
console.log(data);
});
console.log('这行代码会立即执行,不会等待文件读取完成');
事件循环机制:
- 执行同步代码
- 处理微任务队列 (Promise, process.nextTick)
- 处理宏任务队列 (setTimeout, setInterval, I/O 回调)
- 重复循环
2.3 模块系统
CommonJS (Node.js 默认模块系统)
// 导出模块 (math.js)
exports.add = (a, b) => a + b;
// 或
module.exports = {
add: (a, b) => a + b
};
// 导入模块
const math = require('./math');
console.log(math.add(2, 3));
ES Modules (现代 JavaScript 模块标准)
// package.json 中设置 "type": "module"
// 或使用 .mjs 后缀
// 导出 (math.mjs)
export const add = (a, b) => a + b;
// 导入
import { add } from './math.mjs';
console.log(add(2, 3));
三、快速开始:安装与第一个应用
3.1 安装 Node.js
推荐方式:
- 访问官网 https://nodejs.org
- 下载 LTS (长期支持版) 并安装
- 安装包自带 npm (Node Package Manager)
验证安装:
node -v # 查看 Node.js 版本
npm -v # 查看 npm 版本
国内用户建议:
npm config set registry https://registry.npmmirror.com # 设置为淘宝镜像
3.2 第一个 Node.js 应用
创建 hello.js 文件:
// hello.js
console.log('Hello, Node.js!');
运行:
node hello.js
第一个 HTTP 服务器:
// server.js
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello from Node.js server!\n');
});
server.listen(3000, () => {
console.log('服务器运行在 http://localhost:3000');
});
运行服务器:
node server.js
# 然后在浏览器访问 http://localhost:3000
四、Node.js 基础语法与全局对象
4.1 基本语法
变量声明:
let name = 'Alice'; // 可重新赋值
const age = 25; // 常量,不可重新赋值
var oldWay = '不推荐'; // 旧方式,存在作用域问题
函数定义:
// 函数声明
function greet(name) {
return `Hello, ${name}!`;
}
// 箭头函数
const greetArrow = (name) => `Hello, ${name}!`;
console.log(greet('Bob')); // Hello, Bob!
4.2 Node.js 全局对象
常用全局对象:
global:全局命名空间(类似浏览器中的 window)console:控制台输出process:当前进程信息Buffer:处理二进制数据setInterval/setTimeout:定时器require/module/exports:模块系统
process 对象示例:
console.log('当前 Node.js 版本:', process.version);
console.log('操作系统平台:', process.platform);
console.log('命令行参数:', process.argv);
五、Node.js 核心模块实战
5.1 文件系统模块 (fs)
异步读取文件:
const fs = require('fs');
fs.readFile('example.txt', 'utf8', (err, data) => {
if (err) {
console.error('读取失败:', err);
return;
}
console.log('文件内容:', data);
});
同步读取文件:
try {
const data = fs.readFileSync('example.txt', 'utf8');
console.log('文件内容:', data);
} catch (err) {
console.error('读取失败:', err);
}
5.2 HTTP 模块
创建简单 HTTP 服务器:
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('<h1>Hello from Node.js HTTP Server!</h1>');
});
server.listen(3000, () => {
console.log('服务器运行在 http://localhost:3000');
});
5.3 路径处理模块 (path)
const path = require('path');
const filePath = '/users/home/document.txt';
console.log('文件名:', path.basename(filePath)); // document.txt
console.log('目录名:', path.dirname(filePath)); // /users/home
console.log('文件扩展名:', path.extname(filePath)); // .txt
console.log('规范化路径:', path.normalize('/users//home/../home/file.txt'));
六、异步编程:从回调到 async/await
6.1 回调函数 (Callback)
function fetchData(callback) {
setTimeout(() => {
callback(null, '数据获取成功');
}, 1000);
}
fetchData((err, data) => {
if (err) {
console.error('错误:', err);
return;
}
console.log('结果:', data);
});
6.2 Promise
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve('数据获取成功');
} else {
reject(new Error('数据获取失败'));
}
}, 1000);
});
}
fetchData()
.then(data => console.log('结果:', data))
.catch(err => console.error('错误:', err));
6.3 async/await (推荐)
async function getData() {
try {
const data = await fetchData();
console.log('结果:', data);
} catch (err) {
console.error('错误:', err);
}
}
getData();
1564

被折叠的 条评论
为什么被折叠?



