📌 核心知识点:
Node.js 使用“回调函数”来处理异步操作,实现非阻塞 I/O,从而高效应对大量并发请求。
🤔 为什么需要“非阻塞”?
想象一下你在餐厅点餐:
- ❌ 阻塞方式(传统语言如 PHP):
你点完菜后,服务员站在你桌边等厨房做好再走 —— 这期间他不能服务其他人。 - ✅ 非阻塞方式(Node.js):
你点完菜,服务员记下订单就去服务下一位客人;菜好了厨房通知他,他再把菜端给你。
👉 Node.js 就是这个“聪明的服务员”,用 事件 + 回调 实现高效并发。
🔁 什么是回调函数?
简单说: “等我做完这件事,就去执行你给我的函数”
示例:setTimeout
console.log("第一步:开始");
setTimeout(() => {
console.log("第三步:2秒后执行");
}, 2000);
console.log("第二步:不会等上面");
输出顺序:
第一步:开始
第二步:不会等上面
(等待2秒)
第三步:2秒后执行
✅ 虽然 setTimeout 在中间定义,但它的回调函数最后才执行,而且 不会阻塞后面的代码!
💡 回调在 Node.js 中的真实用途
比如读取一个大文件:
❌ 同步读取(会卡住程序)
const fs = require('fs');
console.log('开始读取文件...');
const data = fs.readFileSync('big-file.txt', 'utf8'); // 卡在这里直到读完
console.log('文件读取完成!');
console.log('程序继续运行...');
⚠️ 如果文件很大,这期间整个程序都“冻结”了,无法响应其他请求。
✅ 异步读取(推荐!使用回调)
const fs = require('fs');
console.log('开始读取文件...');
fs.readFile('big-file.txt', 'utf8', (err, data) => {
if (err) {
console.error('读取失败:', err);
return;
}
console.log('文件读取完成!');
console.log('内容长度:', data.length);
});
console.log('我不等你,我先走了!');
输出顺序:
开始读取文件...
我不等你,我先走了!
(稍后...)
文件读取完成!
内容长度: 102400
🎉 成功做到了“不等待”!这就是 非阻塞 I/O。
📌 回调函数的标准格式
在 Node.js 中,大多数异步方法的回调函数长这样:
function(err, result) {
if (err) {
// 处理错误
} else {
// 使用 result
}
}
👉 这叫 Error-First Callback(错误优先回调),是 Node.js 的约定。
✅ 小结一句话:
回调函数是 Node.js 实现“异步、非阻塞”的核心方式:告诉系统“事情做完后调用我这个函数”,而不是傻等结果。
🧠 类比记忆:
| 生活场景 | 对应编程概念 |
|---|---|
| 点外卖后继续工作,收到通知再去拿 | 回调函数 |
| 给快递员留纸条:“送到后打电话给我” | 注册回调 |
| 快递没送到是因为地址错 → 收到电话说送不了 | 错误优先回调中的 err |
📬 下一课预告:
第 9 课:回调地狱(Callback Hell)与解决方案 —— 如何避免层层嵌套?
我们将看到当多个异步操作串联时会出现什么问题,以及如何解决它。