node.js知识系列(2)-每天了解一点

简介: node.js知识系列(2)-每天了解一点

11. 执行子进程(child processes)

Node.js 中,您可以使用 child_process 模块来执行子进程。这允许您在 Node.js 应用程序中启动外部命令或脚本,与它们进行交互并获取输出。

以下是一个简单的子进程执行示例,调用 ls 命令列出目录内容:

const { exec } = require('child_process');
exec('ls', (error, stdout, stderr) => {
  if (error) {
    console.error(`执行出错: ${error}`);
    return;
  }
  console.log(`stdout: ${stdout}`);
  console.error(`stderr: ${stderr}`);
});

场景示例:在一个 Web 服务器上,您可以使用子进程执行一个 Python 脚本,该脚本根据请求动态生成图像并将其返回给客户端。

12. Express.js 中的 WebSocket 库

Express.js 本身不包含 WebSocket 支持,但您可以使用第三方 WebSocket 库,如 socket.io,来与 Express.js 集成以实现实时通信。这些库使得建立 WebSocket 连接和处理实时消息变得更加容易。

使用 socket.io 可以创建 WebSocket 服务器并与 Express.js 服务器一起运行,允许客户端和服务器之间的双向通信。典型的应用场景包括实时聊天、实时通知、在线游戏等。

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = socketIo(server);
io.on('connection', (socket) => {
  console.log('客户端连接');
  socket.on('message', (message) => {
    console.log(`收到消息:${message}`);
    io.emit('message', message); // 广播消息给所有连接的客户端
  });
  socket.on('disconnect', () => {
    console.log('客户端断开连接');
  });
});
server.listen(3000, () => {
  console.log('服务器正在监听端口 3000');
});

13. 请求体解析

在 Express.js 中,请求体解析是指将来自客户端的请求数据解析成 JavaScript 对象,以便在路由处理函数中进行处理。Express.js 提供了不同的中间件来处理不同类型的请求数据,包括 JSON 数据和表单数据。

  • 处理 JSON 数据:使用 express.json() 中间件来解析 JSON 请求体。
const express = require('express');
const app = express();
app.use(express.json());
app.post('/api/data', (req, res) => {
  const jsonData = req.body; // 解析后的 JSON 数据
  // 处理 JSON 数据
});
  • 处理表单数据:使用 express.urlencoded() 中间件来解析表单数据。
app.use(express.urlencoded({ extended: true }));
app.post('/api/form', (req, res) => {
  const formData = req.body; // 解析后的表单数据
  // 处理表单数据
});
  • 处理表单数据:使用 express.urlencoded() 中间件来解析表单数据。
app.use(express.urlencoded({ extended: true }));
app.post('/api/form', (req, res) => {
  const formData = req.body; // 解析后的表单数据
  // 处理表单数据
});

这些中间件将请求体数据解析为 JavaScript 对象,使您可以轻松地处理和操作它们。

14. 包装回调函数(Promisify)

Node.js 中的包装回调函数是将具有回调风格的函数转换为返回 Promise 的函数的过程。这使得可以更容易地使用异步函数和 async/await 语法进行编程,同时具有更好的错误处理能力。

例如,Node.js 内置的 fs 模块提供了回调风格的文件操作函数,您可以使用 util.promisify 来将它们包装成 Promise 风格的函数:

const fs = require('fs');
const util = require('util');
const readFileAsync = util.promisify(fs.readFile);
readFileAsync('file.txt', 'utf8')
  .then((data) => {
    console.log(data);
  })
  .catch((err) => {
    console.error(err);
  });

util.promisify 会将回调函数包装成返回 Promise 的函数,这样您可以更方便地使用 async/await 处理异步操作。

15. 事件发射器(EventEmitter)模式

Node.js 的事件发射器模式是一种用于处理事件和异步操作的设计模式。它在实际应用中用于以下方面:

  • 自定义事件:您可以创建自己的事件发射器类,并定义事件类型。这在构建可扩展的应用程序时非常有用,因为它允许不同的组件在事件触发时相应地做出响应。
  • 异步通知:事件发射器允许对象在异步操作完成时通知观察者或订阅者。例如,在文件读取完成后触发一个事件通知。
  • 解耦组件:事件发射器可以用于解耦应用程序组件,使它们不需要直接依赖于彼此的实现细节,从而提高代码的可维护性和可测试性。

一个常见的内置事件发射器是 Node.js 的 EventEmitter 类,您可以继承它来创建自己的事件发射器。例如,一个简单的事件发射器用于处理文件读取完成事件:

const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('fileRead', (data) => {
  console.log('文件读取完成:', data);
});
// 模拟文件读取操作
setTimeout(() => {
  myEmitter.emit('fileRead', '文件内容...');
}, 1000);

在上述示例中,MyEmitter 类继承自 EventEmitter,并用于触发和处理自定义事件。

16. Event Loop 阶段

Node.js 的 Event Loop 有几个阶段,每个阶段都负责不同类型的任务。这些阶段包括:

  1. Timers(定时器):处理定时器和 setTimeout 回调函数。
  2. Pending Callbacks(挂起的回调):用于执行延迟到下一个循环迭代的 I/O 回调函数。
  3. Idle, Prepare(空闲,准备):仅在内部使用,无需关心。
  4. Poll(轮询):等待新的 I/O 事件,如文件读取、网络请求等。
  5. Check(检查):执行 setImmediate 回调函数。
  1. Close Callbacks(关闭回调):处理关闭事件,例如 socket.on('close', ...)

Event Loop 在这些阶段之间循环运行,每个阶段执行相应的任务。当一个阶段的任务全部完成后,Event Loop 会移动到下一个阶段。这个过程会不断重复,使得 Node.js 能够处理异步操作和事件。

17. 大规模文件上传和下载

对于大规模文件上传和下载,Node.js 提供了一种流式处理的方式,以避免内存溢出。您可以使用可读流(Readable Stream)来逐块地读取上传的文件,然后使用可写流(Writable Stream)将数据写入目标文件或发送给客户端。

以下是一个使用 Express.js 处理文件上传的示例:

const express = require('express');
const multer = require('multer'); // 处理文件上传的中间件
const fs = require('fs');
const app = express();
// 配置文件上传
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'uploads/');
  },
  filename: (req, file, cb) => {
    cb(null, file.originalname);
  },
});
const upload = multer({ storage });
// 处理文件上传
app.post('/upload', upload.single('file'), (req, res) => {
  res.send('文件上传成功');
});
app.listen(3000, () => {
  console.log('服务器正在监听端口 3000');
});

在上述示例中,使用 multer 中间件处理文件上传,它会将文件逐块保存到服务器上的磁盘,而不会将整个文件加载到内存中。

18. 可读流和可写流

可读流和可写流是 Node.js 中的流式处理机制的核心组件。它们用于高效地处理数据流,例如文件读取、网络传输、数据处理等。

一些使用案例包括:

  • 文件读取:使用可读流逐行读取大型日志文件,而不必一次性加载整个文件。
  • HTTP 响应:在服务器响应中使用可写流,逐块地发送响应数据给客户端。
  • 数据转换:使用可读流和可写流来执行数据转换,例如压缩、解压缩、加密、解密等。
  • 网络传输:在网络通信中使用可读流和可写流来处理数据的传输和接收。

流使得处理大型数据变得更加高效和可控,同时减少内存使用。

19. 管理环境变量

在 Node.js 中,可以使用 process.env 来访问环境变量。环境变量通常用于存储配置信息、敏感数据、数据库连接字符串等。

一些最佳实践包括:

  • 将敏感信息存储在环境变量中,而不是硬编码在代码中。
  • 使用 .env 文件或配置管理工具来管理不同环境下的变量。
  • 使用 dotenv 包来加载 .env 文件中的变量。
  • 在生产环境中确保敏感信息的安全性,例如使用环境变量管理工具或服务器配置。

20. 性能分析工具

Node.js 提供了一些内置和第三方工具来进行性能分析:

  • V8 Profiler:内置于 Node.js 中的性能分析工具,可用于分析代码的性能瓶颈。
  • npm 包:有很多第三方调试和性能分析工具,例如 debug 包、nodemonpm2 等,可以根据需要选择合适的工具。

性能分析工具有助于查找和解决应用程序中的问题,优化性能,并提供更好的用户体验。使用这些工具,可以更深入地了解应用程序的运行情况并进行必要的优化。

相关文章
|
7月前
|
缓存 JavaScript 中间件
node.js知识系列(5)-每天了解一点
node.js知识系列(5)-每天了解一点
42 0
|
7月前
|
Web App开发 JavaScript 前端开发
node.js知识系列(1)-每天了解一点
node.js知识系列(1)-每天了解一点
34 1
|
7月前
|
JSON JavaScript 前端开发
node.js知识系列(4)-每天了解一点
node.js知识系列(4)-每天了解一点
26 1
|
7月前
|
存储 JavaScript 前端开发
node.js知识系列(3)-每天了解一点
node.js知识系列(3)-每天了解一点
25 1
|
9月前
|
Kubernetes 负载均衡 监控
K8s入门基础篇:Node组件的介绍
K8s入门基础篇:Node组件的介绍
316 1
|
10月前
|
缓存 JavaScript API
Node冷门知识点——require('node:path')
今天在看Vite的源码时候,发现有个用法很神奇
126 0
|
10月前
|
JSON JavaScript 前端开发
Node冷门知识点—— node.js支持import语法
Node冷门知识点—— node.js支持import语法
639 0
|
12月前
|
运维 监控 JavaScript
Node.js躬行记(22)——Node环境升级日志
Node.js躬行记(22)——Node环境升级日志
|
网络协议 JavaScript 前端开发
前端需要去了解的nodejs知识(dgram)
对于前端开发,http服务是我们最长接触的通信服务,偶尔也会用到一些类似于聊天框的长链接应用,这些应用都不是基于HTTP开发的,HTTP是是无状态的短连接,说到长连接是不是首先会想到TCP,TCP是有状态的长连接协议。TCP和HTTP都是有连接的意思就是通信前需要建立连接,但是在计算机网络世界还有种无连接的协议UDP,下面我们就来了解下TCP在nodejs中的应用。
|
Web App开发 缓存 JavaScript
前端需要去了解的nodejs知识(基础篇)
无论是前端开发还是后台开发个人认为都不应该局限于自己所在的领域,多去突破舒适圈才能有所提升,孰虽然能生巧,但我们也要知道学而不思则惘,所以了解下和前端关联最深的服务端知识很有必要,而nodejs的出现可以说是使得前端开发去了解后台有了更为快捷的路径。以下是自己以前端的角度去学习nodejs的一些经验。