用NODE.JS中的流编写工具是要注意的事项
Node.js中的流处理是一个强大的特性,尤其对于处理大文件或数据流时,它提供了一种高效且灵活的方式。默认情况下,Node.js的流是以buffer的形式进行传输的,但你也可以为其设置其他的编码形式。在基于流编写工具函数或库时,有一些关键的点需要注意。
我们需要警惕EVENTEMITTER内存泄露。在一个可能被多次调用的函数中,如果我们需要给流添加事件监听器来执行某些操作,就需要特别小心。每次添加事件监听器,都会增加事件发射器的监听器数量。当这个数量超过默认限制时,Node.js会发出警告,告诉我们可能发生了内存泄露。
例如,在以下代码中:
```javascript
'use strict';
const fs = require('fs');
function getSomeDataFromStream(stream) {
// ... some code ...
}
let stream = fs.createReadStream('/Path/to/a/big/file');
// 每次调用getSomeDataFromStream函数时,都会为stream添加新的error和end事件监听器
while (true) {
getSomeDataFromStream(stream);
}
```
每次调用`getSomeDataFromStream`函数时,都会为传入的流添加新的error和end事件监听器。由于这些监听器没有被正确清理,当监听器的数量超过默认限制时,就会触发内存泄露警告。
为了避免这种情况,我们可以在函数结束时移除事件监听器,或者使用`emitter.setMaxListeners(n)`来增加允许的最大监听器数量。但最好的做法还是确保你的代码在不再需要监听器时正确地移除它们。
当你处理流时,还需要注意流的读取和写入操作。使用流的优势在于它可以异步处理大量数据,而不需要一次性将所有数据加载到内存中。当你从流中读取数据时,不要一次性读取整个流的内容,而是使用可迭代协议逐步处理数据。这样可以避免一次性加载大量数据导致的内存压力。
一、避免内存泄露并清理监听器
```javascript
function getSomeDataFromStream(stream) {
return new Promise((resolve, reject) => {
let dataReceived = false; // 用于标识数据是否接收完毕
let streamEnded = false; // 用于标识流是否结束
let errorOccurred = false; // 用于标识是否发生错误
let data; // 存储接收到的数据
stream.once('readable', () => {
data = stream.read(); // 当可读时读取数据
dataReceived = true; // 标记数据已接收
checkResolve(); // 检查是否满足条件进行resolve或reject
});
stream.on('error', (err) => {
errorOccurred = true; // 发生错误时标记为true
checkReject(err); // 检查错误并进行reject操作
});
stream.on('end', () => {
streamEnded = true; // 标记流已结束
checkResolve(); // 检查是否所有数据都已处理完毕并进行resolve操作
});
function checkResolve() {
if (dataReceived && streamEnded && !errorOccurred) { // 如果数据接收完毕且流已结束且没有错误发生,则resolve返回数据
resolve(data);
} else if (errorOccurred) { // 如果发生错误,则reject错误原因
reject(new Error('Error occurred during stream processing.'));
} else { // 其他情况则等待事件继续触发并重新检查条件是否满足
编程语言
- 用NODE.JS中的流编写工具是要注意的事项
- 基于react后端渲染模板引擎noox发布使用
- MySql批量插入优化Sql执行效率实例详解
- 浅析JavaScript动画
- js如何判断输入字符串长度
- 从PHP $_SERVER相关参数判断是否支持Rewrite模块
- PHP基于mcript扩展实现对称加密功能示例
- 如何动态查看及加载PHP扩展
- 微信小程序 video组件详解
- Git 教程简单入门介绍
- bootstrap下拉框动态赋值方法
- JavaScript页面倒计时功能完整示例
- 隐藏在SQLServer 字段中的超诡异字符解决过程
- Yii框架实现邮箱激活的方法【数字签名】
- 利用 Linq+Jquery+Ajax 实现异步分页功能可简化带宽
- 总结对比php中的多种序列化