const stream = require('stream')
const readable = new stream.Readable({
encoding: 'utf8',
highWaterMark: 16000,
objectMode: false
})
const news = [
'News #1',
'News #2',
'News #3'
]
readable._read = () => {
if(news.length) {
return readable.push(news.shift() + '\n')
}
return readable.push(null)
}
readable.on('readable', () => {
let data = readable.read()
if(data) {
process.stdout.write(data)
}
})
readable.on('end', () => {
console.log('No more feed')
})
为什么这段代码有效?当缓冲区中有一些数据时,会触发'可读'。如果我没有在流中推送任何数据,为什么这样可行呢?我只在调用'_read'时阅读。我没有打电话给它,为什么它会触发可读事件?我是node.js的noob,刚刚开始学习。
如果你阅读文档,它清楚地提到readable._read(size)
这个函数不能直接由应用程序代码调用。它应该由子类实现,并且只能由内部的Readable类方法调用。
在您的代码中,您已经实现了内部_read
,因此当您执行readable.read()
代码时,您的实现将在内部调用,因此代码将执行。如果您注释掉readable._read = ...
或重命名为代码中的其他内容,您将看到此错误:
Error [ERR_METHOD_NOT_IMPLEMENTED]: The _read() method is not implemented
同样来自docs:The 'readable' event is emitted when there is data available to be read from the stream.
所以,因为在你的代码中有源news
的数据,事件就被解雇了。如果你没有提供任何东西,比如read() { }
,那么就没有地方可以阅读了,所以它没有被解雇。
还有The 'readable' event will also be emitted once the end of the stream data has been reached but before the 'end' event is emitted.
所以说你有:
const news = null;
if(news) {
return readable.push(news.shift() + '\n')
}
// this line is pushing 'null' which triggers end of stream
return readable.push(null)
然后readable
事件被解雇,因为它已到达流的末端,但end
尚未被解雇。
您应该将read
选项作为按照文档read <Function> Implementation for the stream._read() method.
的函数传递
const stream = require('stream')
const readable = new stream.Readable({
read() {
if(news.length) {
return readable.push(news.shift() + '\n')
}
return readable.push(null)
},
encoding: 'utf8',
highWaterMark: 16000,
objectMode: false
})