什么时候'可读'事件实际发出? stream.Readable

问题描述 投票:0回答:1
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,刚刚开始学习。

javascript node.js stream buffer
1个回答
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
})
© www.soinside.com 2019 - 2024. All rights reserved.