Javascript stream.Transform在节点中究竟是如何工作的?
下面是我在博客上在线找到的一段代码片段,其中包含一个简单的示例,使用stream Transform类更改数据流并输出更改后的结果。关于这件事,有些事情我真的不明白Javascript stream.Transform在节点中究竟是如何工作的?,javascript,node.js,express,constructor,prototype,Javascript,Node.js,Express,Constructor,Prototype,下面是我在博客上在线找到的一段代码片段,其中包含一个简单的示例,使用stream Transform类更改数据流并输出更改后的结果。关于这件事,有些事情我真的不明白 var stream = require('stream'); var util = require('util'); // node v0.10+ use native Transform, else polyfill var Transform = stream.Transform || require('readable
var stream = require('stream');
var util = require('util');
// node v0.10+ use native Transform, else polyfill
var Transform = stream.Transform ||
require('readable-stream').Transform;
为什么程序需要检查this var是否指向上层构造函数的实例?上层构造函数用于构造下面的上层对象,那么检查这一点的原因是什么?另外,我尝试了日志选项,但它返回null/undefined,那么该参数的意义是什么
function Upper(options) {
// allow use without new
if (!(this instanceof Upper)) {
return new Upper(options);
}
我假设这个Transform.call方法是用来显式设置this变量的?但是为什么程序会这样做,因为无论如何都不会调用Transform
// init Transform
Transform.call(this, options);
}
通过谷歌搜索util包后,我知道这里使用它是为了允许Upper继承Transform的原型方法。是这样吗
util.inherits(Upper, Transform);
下面的函数让我很困惑。我知道该程序正在Upper的原型上设置一种方法,用于将输入的数据转换为原型。但是,我根本看不到在哪里调用这个函数
Upper.prototype._transform = function (chunk, enc, cb) {
var upperChunk = chunk.toString().toUpperCase();
this.push(upperChunk);
cb();
};
// try it out - from the original code
var upper = new Upper();
upper.pipe(process.stdout); // output to stdout
通过调试器运行代码后,我可以看到upper.write调用前面提到的upper.prototype.\u transform方法,但为什么会发生这种情况?upper是upper构造函数的一个实例,write是一个似乎与应用于upper原型的_变换方法没有任何关系的方法
upper.write('hello world\n'); // input line 1
upper.write('another line'); // input line 2
upper.end(); // finish
首先,如果您还没有,请查看转换流实现者的文档
- Q:为什么程序需要检查this var是否指向上层构造函数的实例?上层构造函数用于构造下面的上层对象,那么检查这一点的原因是什么
- A:需要检查,因为任何人都可以调用
,而无需Upper()
。因此,如果检测到用户调用构造函数时没有使用new
,出于方便(并使事情正常工作),则会代表用户隐式调用new
new
- Q:另外,我尝试了日志选项,但它返回null/undefined,那么该参数有什么意义呢
- A:
只是一个构造函数/函数参数。如果您没有将任何内容传递给构造函数,那么显然它将是未定义的(或者传递给它的任何值)。您可以拥有任意数量的参数,就像任何普通函数一样。但是,在选项
的情况下,由于转换的简单性(只需将所有输入转换为大写),因此实际上不需要配置Upper()
- Q:我假设这个Transform.call方法是用来显式设置这个变量的?但是为什么程序会这样做,因为无论如何都不会调用Transform
- A:否,
允许继承的“类”执行自己的初始化,例如设置内部状态变量。您可以将其视为在ES6类中调用Transform.call()
super()
- Q:通过谷歌搜索util包后,我知道这里使用它是为了允许Upper继承Transform的原型方法。是这样吗
- A:是的,没错。然而,现在您还可以使用ES6类来进行真正的继承。显示了这两种继承方法的示例
- Q:下面的函数让我很困惑。我知道该程序正在Upper的原型上设置一种方法,用于将输入的数据转换为原型。但是,我根本看不到在哪里调用这个函数
Upper.prototype._transform = function (chunk, enc, cb) {
var upperChunk = chunk.toString().toUpperCase();
this.push(upperChunk);
cb();
};
// try it out - from the original code
var upper = new Upper();
upper.pipe(process.stdout); // output to stdout
- Q:通过调试器运行代码后,我可以看到upper.write调用前面提到的upper.prototype.\u transform方法,但为什么会发生这种情况?upper是upper构造函数的一个实例,write是一个似乎与应用于upper原型的_变换方法没有任何关系的方法
- A:如中所述,转换流只是简化的双工流(意味着它们接受输入并产生输出)。调用
时,您正在写入转换流的可写(输入)端。这就是用您刚刚传递给.write()
的数据触发对.write()
调用的原因。调用.transform()
时,您正在写入转换流的可读(输出)端。当您在转换流上调用.push()
或附加.read()
事件处理程序时,就会看到该数据'data'
- Q:为什么程序需要检查this var是否指向上层构造函数的实例?上层构造函数用于构造下面的上层对象,那么检查这一点的原因是什么
- A:需要检查,因为任何人都可以调用
,而无需Upper()
。因此,如果检测到用户调用构造函数时没有使用new
,出于方便(并使事情正常工作),则会代表用户隐式调用new
new
- Q:同样,