为什么要错误地销毁流?

5 events pipe stream node.js

我看到一些模块以可写流形式传递可读流,并且如果发生任何错误,它们将使用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);
});
Run Code Online (Sandbox Code Playgroud)

销毁流并删除可写流上的close事件有什么必要?如果我不这样做,会发生什么?

谢谢。

Jos*_*ada 1

我相信这是避免内存泄漏所必需的。根据 Node.js 文档中关于Readable.pipe() 方法的内容

一个重要的警告是,如果可读流在处理过程中发出错误,可写目标不会自动关闭。如果发生错误,则需要手动关闭每个流以防止内存泄漏。

在下面的脚本中,注释掉该行w.destroy(err)并注意没有发出任何 Writeable 事件。不知道为什么 Node.js 设计者选择不自动销毁 Writeable,也许他们不希望 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)
Run Code Online (Sandbox Code Playgroud)