流上的 .pipe 和管道有什么区别

Que*_*wer 11 stream node.js

我在 node.js 中找到了两种不同的管道流方法

.pipe()流的众所周知的方法

https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options

和流的独立功能

https://nodejs.org/api/stream.html#stream_stream_pipeline_streams_callback

我应该使用哪一个,这两者之间有什么好处?

Ida*_*gan 11

TL;DR - You better want to use pipeline

What's pipeline?

From the docs: A module method to pipe between streams forwarding errors and properly cleaning up and provide a callback when the pipeline is complete.

What's the motivation for using pipeline?

? Let's take a look at the following code:

const { createReadStream } = require('fs');
const { createServer } = require('http');
const server = createServer(
  (req, res) => {
    createReadStream(__filename).pipe(res);
  }
);

server.listen(3000);
Run Code Online (Sandbox Code Playgroud)

What's wrong here? If the response will quit or the client closes the connection - then the read stream is not closed or destroy which leads to a memory leak.

?So if you use pipeline, it would close all other streams and make sure that there are no memory leaks.

const { createReadStream } = require('fs');
const { createServer } = require('http');
const { pipeline } = require('stream');

const server = createServer(
  (req, res) => {
    pipeline(
      createReadStream(__filename),
      res,
      err => {
        if (err)
          console.error('Pipeline failed.', err);
        else
          console.log('Pipeline succeeded.');
      }
    );
  }
);

server.listen(3000);
Run Code Online (Sandbox Code Playgroud)

  • 该文档还指出,这个几乎完全相同的示例禁止您与“res”交互。因此,您无法发回“500”状态,因为当“createReadStream”关闭时,它也会关闭“res”。*然后*它调用回调。这并不意味着它是“坏”的。请小心。 (4认同)

小智 5

根据文档,他们都做同样的事情。但是有一些区别:

  • .pipe()是 的方法Readable,而pipelinestream接受流到管道的模块方法。
  • pipeline() 方法在管道完成时提供回调。
  • pipeline()方法是从 node 10 版本开始添加的,而.pipe从最早版本的 Node.js 开始就存在。

在我看来,withpipeline()代码看起来更简洁一些,但您可以同时使用它们。

示例.pipe()

const fs = require('fs');
const r = fs.createReadStream('file.txt');
const z = zlib.createGzip();
const w = fs.createWriteStream('file.txt.gz');
r.pipe(z).pipe(w);
Run Code Online (Sandbox Code Playgroud)

示例pipeline()

const { pipeline } = require('stream');
const fs = require('fs');
const zlib = require('zlib');

pipeline(
  fs.createReadStream('archive.tar'),
  zlib.createGzip(),
  fs.createWriteStream('archive.tar.gz'),
  (err) => {
    if (err) {
      console.error('Pipeline failed.', err);
    } else {
      console.log('Pipeline succeeded.');
    }
  }
);
Run Code Online (Sandbox Code Playgroud)