请求解析Node.js中Readable.call(this)的this含义及代码运行原理
理解Node.js中的
this关键字与Readable流继承代码的运行机制 嘿,我来帮你把这事儿掰扯清楚!Node.js里的this确实容易绕,尤其是在继承流这种场景下,咱们一步一步来拆解。
先搞懂Readable.call(this)里的this是什么
当你调用new Counter()创建一个Counter实例的时候,Counter构造函数内部的this,就是这个刚被创建出来的Counter实例对象。
Readable.call(this)这行代码的作用,是把Readable构造函数里的初始化逻辑,绑定到当前这个Counter实例上执行——简单说就是“借”Readable的构造函数,给咱们的Counter实例装上可读流的基础属性和能力(比如流的状态管理、事件触发机制这些底层逻辑),这是JavaScript实现构造函数继承的经典手法。
逐行拆解整个代码的运行机制
先把完整代码贴出来(修正了原代码的转义字符):
var Readable = require('stream').Readable; var util = require('util'); function Counter() { Readable.call(this); this._max = 1000; this._index = 1; } util.inherits(Counter, Readable); Counter.prototype._read = function () { var i = this._index++; if (i > this._max) this.push(null); else { var str = ' ' + i; this.push(str); } };
咱们一行一行看:
var Readable = require('stream').Readable;:引入Node.js内置的可读流构造函数,它是所有自定义可读流的“基类”,提供了流的核心能力。var util = require('util');:引入Node.js的util工具模块,里面的inherits方法专门用来处理原型链继承。function Counter() { ... }:定义咱们自己的可读流构造函数Counter:Readable.call(this);:刚才已经解释过,给Counter实例注入Readable的基础能力,让它具备可读流的“身份”。this._max = 1000;:给Counter实例添加自定义属性,标记计数的上限是1000。this._index = 1;:初始化计数的起始值,从1开始。
util.inherits(Counter, Readable);:把Counter的原型对象的__proto__指向Readable的原型对象,这样Counter实例就能继承Readable原型上的所有方法(比如pipe()、on('data')这些常用的流方法)。这一步和前面的Readable.call(this)配合,就完成了完整的继承——既继承了构造函数里的属性,又继承了原型链上的方法。Counter.prototype._read = function () { ... }:这是自定义可读流必须实现的核心方法!当流需要向外部提供数据的时候,Node.js的流机制会自动调用这个方法:var i = this._index++;:先取当前的计数,然后把计数器自增,为下一次调用做准备。if (i > this._max) this.push(null);:如果计数超过了上限,就调用push(null)——这是可读流的约定:push(null)表示“我没有更多数据了,流可以结束了”,之后流会触发end事件。else { ... }:如果没到上限,就把当前数字转成带空格的字符串,然后push(str)把数据放到流的缓冲区里,下游代码(比如监听data事件的回调)就能读到这段数据。
补充:代码的实际运行流程
当你创建Counter实例后:
- 一旦你监听它的
data事件,或者调用pipe()把它接到另一个流上,Node.js就会自动触发_read方法。 - 每次
_read被调用,就会生成一段数据(数字字符串),直到push(null)。 - 当
push(null)后,流会触发end事件,告诉下游数据已经全部传输完成。
内容的提问来源于stack exchange,提问作者J. Colar
相关产品推荐
相关产品推荐

