何时实际发出“可读”事件?流。可读

时间:2019-03-30 15:36:30

标签: javascript node.js stream buffer

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不熟悉,并且刚刚开始学习。

1 个答案:

答案 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
})