我看到一些模块在可写流中管道可读流,如果发生任何错误,它们会使用destroy方法:
const readable = fs.createReadStream("file");
const writable = fs.createWriteStream("file2");
readable.pipe(writable);
readable.on("error", (error) => {
readable.destroy();
writable.destroy();
writable.removeListener("close");
callback(error);
});
writable.on("error", (error) => {
readable.destroy();
writable.destroy();
writable.removeListener("close");
callback(error);
});
在可写流上销毁流并删除close事件的必要性是什么?如果我不这样做,会发生什么?
感谢。
答案 0 :(得分:0)
我相信这对于避免内存泄漏是必要的。根据 readable.pipe() method 上的 Node.js 文档,
<块引用>一个重要的警告是,如果可读流在处理过程中发出错误,则可写目标不会自动关闭。如果发生错误,则需要手动关闭每个流以防止内存泄漏。
在下面的脚本中,注释掉 w.destroy(err)
行并注意没有任何可写事件发出。不知道为什么 Node.js 设计者选择不自动销毁可写的,也许他们不希望 Stream.pipe() 过于自以为是。
const r = new Readable({
objectMode: true,
read() {
try {
this.push(JSON.parse('{"prop": "I am the data"'))
this.push(null) // make sure we let Writeable's know there's no more to read
} catch (e) {
console.error(`Problem encountered while reading data`, e)
this.destroy(e)
}
}
}).on('error', (err) => {
console.log(`Reader error: ${err}`)
w.destroy(err)
done()
})
const w = new Writable({
objectMode: true,
write(chunk, encoding, callback) {
callback()
}
}).on('error', (err) => {
console.error(`Writer error: ${err}`)
})
.on('close', () => {
console.error(`Writer close`)
})
.on('finish', () => {
console.error(`Writer finish`)
})
r.pipe(w)