'readable' 事件


当有可从流中读取的数据或已到达流的末尾时,则将触发 'readable' 事件。 实际上,'readable' 事件表明流有新的信息。 如果数据可用,则 stream.read() 将返回该数据。

const readable = getReadableStreamSomehow();
readable.on('readable', function() {
  // 现在有一些数据要读取。
  let data;

  while ((data = this.read()) !== null) {
    console.log(data);
  }
});

如果已经到达流的末尾,则调用 stream.read() 将返回 null 并触发 'end' 事件。 如果从未读取任何数据,则也是如此。 例如,在以下示例中,foo.txt 是一个空文件:

const fs = require('node:fs');
const rr = fs.createReadStream('foo.txt');
rr.on('readable', () => {
  console.log(`readable: ${rr.read()}`);
});
rr.on('end', () => {
  console.log('end');
});

运行此脚本的输出是:

$ node test.js
readable: null
end

在某些情况下,为 'readable' 事件绑定监听器会导致一些数据被读入内部缓冲区。

一般来说,readable.pipe()'data' 事件机制比 'readable' 事件更容易理解。 但是,处理 'readable' 可能会导致吞吐量增加。

如果同时使用 'readable''data',则 'readable' 优先控制流,即只有在调用 stream.read() 时才会触发 'data'readableFlowing 属性将变为 false。 如果在移除 'readable' 时有 'data' 个监听器,则流将开始流动,即 'data' 事件将在不调用 .resume() 的情况下触发。

The 'readable' event is emitted when there is data available to be read from the stream or when the end of the stream has been reached. Effectively, the 'readable' event indicates that the stream has new information. If data is available, stream.read() will return that data.

const readable = getReadableStreamSomehow();
readable.on('readable', function() {
  // There is some data to read now.
  let data;

  while ((data = this.read()) !== null) {
    console.log(data);
  }
});

If the end of the stream has been reached, calling stream.read() will return null and trigger the 'end' event. This is also true if there never was any data to be read. For instance, in the following example, foo.txt is an empty file:

const fs = require('node:fs');
const rr = fs.createReadStream('foo.txt');
rr.on('readable', () => {
  console.log(`readable: ${rr.read()}`);
});
rr.on('end', () => {
  console.log('end');
});

The output of running this script is:

$ node test.js
readable: null
end

In some cases, attaching a listener for the 'readable' event will cause some amount of data to be read into an internal buffer.

In general, the readable.pipe() and 'data' event mechanisms are easier to understand than the 'readable' event. However, handling 'readable' might result in increased throughput.

If both 'readable' and 'data' are used at the same time, 'readable' takes precedence in controlling the flow, i.e. 'data' will be emitted only when stream.read() is called. The readableFlowing property would become false. If there are 'data' listeners when 'readable' is removed, the stream will start flowing, i.e. 'data' events will be emitted without calling .resume().