下面是我在博客上找到的代码片段,其中包含一个使用Stream Transform类来改变数据流并输出更改结果的简单示例。关于这方面的一些事情,我真的不明白。
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是否指向Upper构造函数的实例? Upper构造函数用于构造下面的上层对象,那么检查这个的原因是什么?此外,我尝试了日志选项,但它返回null / undefined,那么该参数的重点是什么?
function Upper(options) {
// allow use without new
if (!(this instanceof Upper)) {
return new Upper(options);
}
我假设这个Transform.call方法正在显式设置这个变量?但是为什么程序会这样做,看看如何永远不会调用Transform。
// init Transform
Transform.call(this, options);
}
在谷歌搜索工具包之后,我知道这里使用它来允许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._transform方法,但为什么会这样呢? upper是Upper构造函数的一个实例,而write是一个方法,似乎与应用于Upper原型的_transform方法没有任何关系。
upper.write('hello world\n'); // input line 1
upper.write('another line'); // input line 2
upper.end(); // finish
答案 0 :(得分:3)
首先,如果您还没有,请查看转化流实施者的文档here。
问:为什么程序需要检查此var是否指向Upper构造函数的实例? Upper构造函数用于构造下面的上层对象,那么检查这个的原因是什么?
答:需要检查,因为任何人都可以在没有 Upper()
的情况下拨打new
。因此,如果用户检测到用户在没有new
的情况下调用了构造函数,方便(并使工作正常),则代表用户隐式调用new
。
问:此外,我尝试了记录选项,但它返回null / undefined,那么该参数的重点是什么?
A: options
只是一个构造函数/函数参数。如果你没有向构造函数传递任何东西,那么显然它将是undefined
(或者你传递给它的任何值)。您可以拥有任意数量的参数,就像任何普通函数一样。但是在Upper()
的情况下,由于转换的简单性(仅将所有输入转换为大写),因此不需要配置。
问:我假设这个Transform.call方法正在显式设置这个变量?但是为什么程序会这样做,看看变形从未被调用过。
答:不,Transform.call()
允许继承的"类"执行自己的初始化,例如设置内部状态变量。您可以将其视为在ES6课程中调用super()
。
问:在Google搜索工具包后,我知道在这里使用它来允许Upper继承Transform的原型方法。是吗?
A:是的,这是正确的。但是,现在您还可以使用ES6类来进行实际继承。 node.js stream implementers documentation显示了两种继承方法的示例。
问:以下功能让我感到困惑。我知道该程序正在设置Upper的原型方法,该方法用于转换输入到其中的数据。但是,我根本不知道这个函数的调用位置!
A:当您有要处理的数据时,此功能由节点在内部调用。可以将该方法视为接口的一部分(或者是#34;纯虚函数"如果您熟悉C ++),则需要在自定义转换中实现该方法。
问:通过调试器运行代码后,我可以看到upper.write调用上述的Upper.prototype._transform方法,但为什么会这样呢? upper是Upper构造函数的一个实例,而write是一个似乎与应用于Upper原型的_transform方法无任何关系的方法。
A:如Transform documentation所述,转换流只是简化双工流(意味着它们接受输入并产生输出)。当您调用.write()
时,您正在写入Transform流的Writable(输入)端。这就是使用刚刚传递给._transform()
的数据触发对.write()
的调用的内容。当您调用.push()
时,您正在写入Transform流的可读(输出)端。当您在转换流上调用.read()
或附加'data'
事件处理程序时,会看到该数据。