为什么要错误地破坏流?

时间:2017-03-30 14:00:55

标签: node.js events stream pipe

我看到一些模块在可写流中管道可读流,如果发生任何错误,它们会使用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事件的必要性是什么?如果我不这样做,会发生什么?

感谢。

1 个答案:

答案 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)