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不熟悉,并且刚刚开始学习。
答案 0 :(得分:0)
如果您阅读文档,它会明确提到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
})