Node.js 把 JavaScript 带出浏览器,靠的是单线程事件循环加非阻塞 I/O。下面这几段是从零跑一个服务、读写文件、再到用流处理大文件时最常用的骨架。
1. 最小 HTTP 服务
import { createServer } from 'node:http';
const server = createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('霍州比特人:hello from node
');
});
server.listen(3000, () => console.log('http://localhost:3000'));
2. 事件循环的顺序
同步代码先跑完,接着是微任务(Promise、queueMicrotask),再进入宏任务各阶段(timers、poll、check…)。setImmediate 属于 check 阶段,setTimeout(fn, 0) 属于 timers,两者的先后在主模块里并不总是固定。
console.log('A');
queueMicrotask(() => console.log('B'));
setTimeout(() => console.log('C'), 0);
setImmediate(() => console.log('D'));
Promise.resolve().then(() => console.log('E'));
console.log('F');
// 常见输出:A F B E C D(C / D 在主模块中可能互换)
3. 文件与流
import { createReadStream, createWriteStream } from 'node:fs';
import { pipeline } from 'node:stream/promises';
import { createGzip } from 'node:zlib';
await pipeline(
createReadStream('access.log'),
createGzip(),
createWriteStream('access.log.gz')
);
pipeline 会替你处理背压和错误传递,比手写 .pipe() 加一堆 error 监听稳得多。大文件永远不要 readFileSync 全读进内存。
4. 模块与常用全局
node --watch server.mjs # 改动自动重启
node --env-file=.env app.mjs # 加载环境变量
npm pkg set type=module # package.json 开启 ESM
import.meta.url配fileURLToPath拿当前文件目录,别再用__dirname猜。process.env.NODE_ENV只做分支,不要把密钥写进代码库。- CPU 密集任务交给
worker_threads,事件循环不适合硬算。
Node 的难点从来不是语法,是记住「这一行会不会把事件循环堵住」。
微信赞赏长按识别 / 扫一扫
支付宝长按识别 / 扫一扫
留言与讨论
评论提交后需作者后台审核才会公开 · 同一 IP 每小时最多 10 条 · 本小时还可发布 10 条