有什么区别:
const stream = createReadStream(source).pipe(createWriteStream(destination));
stream.on("error", (error) => {
stream.destroy();
stream.removeListener("close");
reject(error);
});
stream.on("close", () => {
// do something
});
VS
const writable = createWriteStream(destination);
const readable = createReadStream(source);
readable.on("error", onError);
writable.on("error", onError);
function onError(error) {
readable.destroy();
writable.destroy();
writable.removeListener("close", onClose);
reject(error);
}
如果发生错误,我们为什么要手动销毁流?节点不会自动执行此操作吗?
感谢。
答案 0 :(得分:6)
嗯,有一件事你的第二个例子根本不进行任何管道或数据传输。两者之间唯一的另一个显着差异是,在第一个示例中,您没有附加错误'读取流的事件监听器意味着如果在读取数据时发生错误,则不会捕获错误。你不应该删除"关闭"监听或摧毁流。看起来您正在尝试将文件复制到新位置并让该函数返回Promise。在这种情况下,关闭'关闭'事件发生了火灾,因为Promise只能被解决/拒绝一次。所以如果错误'事件确实会触发,然后您的承诺将被拒绝,并且永远无法解决,因此没有理由删除“关闭”。监听器。此外,节点会在发出错误后自动将流标记为已销毁。这应该是你所需要的:
const fs = require('fs')
function copy (source, target) {
return new Promise((resolve, reject) => {
const rs = fs.createReadStream(source)
const ws = fs.createWriteStream(target)
rs.on('error', reject)
ws.on('error', reject)
rs.pipe(ws).on('close', resolve)
})
}
然后你可以这样使用它:
copy('/foo/bar.json', '/baz/qux.json')
.then(() => console.log('copy done'))