[英]How to properly clear the internal buffer of a readable stream in node?
我正在處理我的自定義轉換流。 由於我手動處理緩沖和緩存,因此我需要確保在重新管道時不會自動發送任何塊。 為此,我應該在嘗試調用.pipe()
。
由於我的流邏輯非常復雜,我制作了這個簡化的示例來幫助您更好地理解我要解決的問題:
const { Readable, Writable } = require('stream')
const wait = ms => new Promise(res => setTimeout(res, ms))
;(async () => {
const readable = new Readable()
readable._read = () => {}
const writable = new Writable()
writable._write = (chunk, _encoding, callback) => {
console.log(chunk.toString())
callback()
}
readable.pipe(writable)
await wait(100) // This small delay replaces listening to the pipe/unpipe events
readable.push('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
console.log('unpipe')
readable.unpipe(writable)
await wait(100)
readable.push('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
// readable.clearInternalBufferOrWhatever() // ???
console.log('pipe')
readable.pipe(writable)
await wait(100)
readable.push('ccccccccccccccccccccccccccccccc')
})()
// => aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa (Expected ✔)
// unpipe
// pipe
// bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb (Unexpected ❌)
// ccccccccccccccccccccccccccccccc (Expected ✔)
如您所見,可寫流已成功接收到第二個塊( 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
),這就是我要避免的。 有任何想法嗎?
我想到了! 流有一個名為_readableState
的內部屬性,其中包含內部緩沖區。 只需兩行代碼即可清除它:
readable._readableState.buffer.clear()
readable._readableState.length = 0
請注意, _readableState
並不安全,因為它是內部的且未記錄在案,並且隨時可能發生重大更改。 但是,已確認此解決方案適用於節點 v8.10.0 和 v14.17.2。
這是一個完整的工作示例:
const { Readable, Writable } = require('stream')
const wait = ms => new Promise(res => setTimeout(res, ms))
;(async () => {
const readable = new Readable()
readable._read = () => {}
const writable = new Writable()
writable._write = (chunk, _encoding, callback) => {
console.log(chunk.toString())
callback()
}
readable.pipe(writable)
await wait(100)
readable.push('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
console.log('unpipe')
readable.unpipe(writable)
await wait(100)
readable.push('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
readable._readableState.buffer.clear()
readable._readableState.length = 0
console.log('pipe')
readable.pipe(writable)
await wait(100)
readable.push('ccccccccccccccccccccccccccccccc')
})()
// => aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
// unpipe
// pipe
// ccccccccccccccccccccccccccccccc
來自 Node 在readable.read()
上的流文檔:
如果沒有數據可供讀取,則返回
null
。
因此,如果我們一直調用readable.read()
直到返回null
,那么內部緩沖區應該被清空。
function clearReadBuffer(readable) {
while (true) {
const chunk = readable.read();
if ( chunk === null ) return;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.