【问题标题】:When is 'readable' event actually emitted? stream.Readable什么时候真正发出“可读”事件?流.可读
【发布时间】:2019-03-30 15:36:29
【问题描述】:
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 的菜鸟,刚刚开始学习。

【问题讨论】:

    标签: javascript node.js stream buffer


    【解决方案1】:

    如果您阅读文档,它清楚地提到了readable._read(size) 此函数不得由应用程序代码直接调用。它应该由子类实现,并且只能由内部 Readable 类方法调用。

    在您的代码中,您已经实现了 internal _read,因此当您执行 readable.read() 的代码时,您的实现被称为 internally,因此代码执行。如果您在代码中注释掉 readable._read = ... 或重命名为其他名称,您将看到此错误:

    Error [ERR_METHOD_NOT_IMPLEMENTED]: The _read() method is not implemented

    同样来自文档: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
    })
    

    【讨论】:

    • 我对@9​​87654336@这个词感到困惑,我以为在你使用push()方法之前没有数据,那么为什么会发出“可读”事件?
    猜你喜欢
    • 1970-01-01
    • 2014-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多