Nodejs 流行为,未调用管道回调
Nodejs stream behaviour, pipeline callback not called
为什么管道从不调用它的回调?
此外,转换功能在 16 个块后停止调用。
例如:
const { Readable, Transform, pipeline } = require('stream');
const readable = new Readable({
objectMode: true,
read() {
this.push(count++);
if (count > 20) {
this.push(null);
}
}
});
const transform = new Transform({
objectMode: true,
transform(chunk, encoding, callback) {
data.push(chunk);
console.log('transform - chunk: ', chunk.toString());
callback(null, chunk);
}
});
let count = 1, data = [];
pipeline(
readable,
transform,
(error) => {
if (error) console.log('pipeline callback - ERROR: ', error);
else console.log('pipeline callback - data: ', data);
}
);
在第 16 次调用后不再调用转换函数是一个提示。
原因在这里给出:
https://nodejs.org/api/stream.html#stream_new_stream_writable_options
在 objectMode 中,转换的默认 highWaterMark 为 16。因为转换函数也将数据“推送”到它自己的可读通过回调,这导致可读缓冲区变满(因为没有进一步的可写来使用可读数据)。
因此,流由于背压而暂停,背压从流的转换可读部分开始,“流动”到转换可写端,然后流到最终暂停的原始可读流。
- transform-readable - 在推送 16 个块后暂停
- transform-writable - 不断接受块并缓冲到上游可读的下一个 16 个块
- 可读 - 一直读取直到其缓冲区已满,接下来的 16 个块,然后暂停
因此原始可读将默认在 16 * 3 个块或 48 次读取后暂停。
当不在objectMode时,buffer/string的highWaterMark是16384字节(虽然setEncoding可以改变这个的意思).
为什么管道从不调用它的回调? 此外,转换功能在 16 个块后停止调用。
例如:
const { Readable, Transform, pipeline } = require('stream');
const readable = new Readable({
objectMode: true,
read() {
this.push(count++);
if (count > 20) {
this.push(null);
}
}
});
const transform = new Transform({
objectMode: true,
transform(chunk, encoding, callback) {
data.push(chunk);
console.log('transform - chunk: ', chunk.toString());
callback(null, chunk);
}
});
let count = 1, data = [];
pipeline(
readable,
transform,
(error) => {
if (error) console.log('pipeline callback - ERROR: ', error);
else console.log('pipeline callback - data: ', data);
}
);
在第 16 次调用后不再调用转换函数是一个提示。 原因在这里给出: https://nodejs.org/api/stream.html#stream_new_stream_writable_options
在 objectMode 中,转换的默认 highWaterMark 为 16。因为转换函数也将数据“推送”到它自己的可读通过回调,这导致可读缓冲区变满(因为没有进一步的可写来使用可读数据)。 因此,流由于背压而暂停,背压从流的转换可读部分开始,“流动”到转换可写端,然后流到最终暂停的原始可读流。
- transform-readable - 在推送 16 个块后暂停
- transform-writable - 不断接受块并缓冲到上游可读的下一个 16 个块
- 可读 - 一直读取直到其缓冲区已满,接下来的 16 个块,然后暂停
因此原始可读将默认在 16 * 3 个块或 48 次读取后暂停。
当不在objectMode时,buffer/string的highWaterMark是16384字节(虽然setEncoding可以改变这个的意思).