readable.unshift(chunk[, encoding])
chunk<Buffer> | <TypedArray> | <DataView> | <string> | <null> | <any> 要加入读取队列的数据块。对于非对象模式的流,chunk必须是 <string>、<Buffer>、<TypedArray>、<DataView> 或null。对于对象模式的流,chunk可以是任意 JavaScript 值。encoding<string> 字符串块的编码。必须是有效的Buffer编码,例如'utf8'或'ascii'。
将 chunk 传递为 null 表示流的结束(EOF),其行为与 readable.push(null) 相同,此后无法再写入数据。EOF 信号会放在缓冲区的末尾,任何已缓冲的数据仍会被刷新。
【Passing chunk as null signals the end of the stream (EOF) and behaves the
same as readable.push(null), after which no more data can be written. The EOF
signal is put at the end of the buffer and any buffered data will still be
flushed.】
readable.unshift() 方法将一块数据推回内部缓冲区。这在某些情况下非常有用,例如流正在被某些代码消费,而这些代码需要“取消消费”它乐观地从源中提取的一些数据,以便这些数据可以传递给其他方。
【The readable.unshift() method pushes a chunk of data back into the internal
buffer. This is useful in certain situations where a stream is being consumed by
code that needs to "un-consume" some amount of data that it has optimistically
pulled out of the source, so that the data can be passed on to some other party.】
stream.unshift(chunk) 方法在 'end' 事件被触发后不能调用,否则会抛出运行时错误。
【The stream.unshift(chunk) method cannot be called after the 'end' event
has been emitted or a runtime error will be thrown.】
经常使用 stream.unshift() 的开发者应考虑改用 Transform 流。有关更多信息,请参阅 流实现者的 API 部分。
【Developers using stream.unshift() often should consider switching to
use of a Transform stream instead. See the API for stream implementers
section for more information.】
// Pull off a header delimited by \n\n.
// Use unshift() if we get too much.
// Call the callback with (error, header, stream).
const { StringDecoder } = require('node:string_decoder');
function parseHeader(stream, callback) {
stream.on('error', callback);
stream.on('readable', onReadable);
const decoder = new StringDecoder('utf8');
let header = '';
function onReadable() {
let chunk;
while (null !== (chunk = stream.read())) {
const str = decoder.write(chunk);
if (str.includes('\n\n')) {
// Found the header boundary.
const split = str.split(/\n\n/);
header += split.shift();
const remaining = split.join('\n\n');
const buf = Buffer.from(remaining, 'utf8');
stream.removeListener('error', callback);
// Remove the 'readable' listener before unshifting.
stream.removeListener('readable', onReadable);
if (buf.length)
stream.unshift(buf);
// Now the body of the message can be read from the stream.
callback(null, header, stream);
return;
}
// Still reading the header.
header += str;
}
}
} 与 stream.push(chunk) 不同,stream.unshift(chunk) 不会通过重置流的内部读取状态来结束读取过程。如果在读取过程中(例如在自定义流的 stream._read() 实现中)调用 readable.unshift(),可能会导致意外结果。在调用 readable.unshift() 后立即进行 stream.push('') 会适当地重置读取状态,但最好在执行读取操作时避免调用 readable.unshift()。
【Unlike stream.push(chunk), stream.unshift(chunk) will not
end the reading process by resetting the internal reading state of the stream.
This can cause unexpected results if readable.unshift() is called during a
read (i.e. from within a stream._read() implementation on a
custom stream). Following the call to readable.unshift() with an immediate
stream.push('') will reset the reading state appropriately,
however it is best to simply avoid calling readable.unshift() while in the
process of performing a read.】