【问题标题】:Directly piping readable stream in writable stream在可写流中直接管道可读流
【发布时间】:2017-08-25 20:20:07
【问题描述】:

有什么区别:

const stream = createReadStream(source).pipe(createWriteStream(destination));

stream.on("error", (error) => {
   stream.destroy();
   stream.removeListener("close");
   reject(error);
});
stream.on("close", () => {
  // do something
});

对比:

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);
}

如果发生错误,我们为什么要手动销毁流? Node 不会自动这样做?

谢谢。

【问题讨论】:

  • 一般来说,我没有看到人们经常破坏流(他们通常会尝试/捕获和拒绝(错误))。此外,第二个版本更易于阅读,因为它将 readStream 和 writeStream 分开
  • 尝试/抓住?为何如此?这是异步的……我认为 try/catch 会失败……
  • 实际上你是对的(与 async/await 混淆了)或 promises。关于你的最后一个问题,我会先阅读一下再回复

标签: javascript node.js events stream


【解决方案1】:

一方面,您的第二个示例根本不执行任何管道或数据传输。两者之间唯一的另一个显着区别是,在第一个示例中,您没有将“错误”事件侦听器附加到读取流,这意味着如果在读取数据时发生错误,您将不会捕获错误。您不需要删除“关闭”侦听器或销毁流。看起来您正在尝试将文件复制到新位置并让函数返回 Promise。在这种情况下,'close' 事件是否触发并不重要,因为 Promise 只能被解决/拒绝一次。因此,如果 'error' 事件确实触发了,那么您的 Promise 将被拒绝并且它永远无法解决,因此没有理由删除 'close' 侦听器。此外,节点在发出错误后会自动将流标记为已销毁。这应该就是您所需要的:

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'))

【讨论】:

    猜你喜欢
    • 2021-03-03
    • 2016-02-17
    • 2018-06-04
    • 1970-01-01
    • 2016-12-15
    • 2018-03-12
    • 1970-01-01
    • 1970-01-01
    • 2023-02-09
    相关资源
    最近更新 更多