繁体   English   中英

管道传输到可写流时暂停可读流

[英]Pause readable stream when piped to writable stream

我有一个我想暂停的可读流。 它通过管道传输到可写流。 我的代码看起来像这样

const { get } = require('https');
const { createWriteStream };

const writableStream = createWriteStream(SOME_PATH);
get(SOME_URL, (res) => {
  res.pipe(writableStream);
  setTimeout(() => {
    res.pause();
  }, 2000);

  setTimeout(() => {
    res.resume();
  }, 4000);
});

这在 Mac 上运行良好。 但出于某种原因,在 Windows 上从https URL 下载时,这不会暂停。

我认为这是因为我的可读流通过管道传输到可写流,而可写流要求更多数据,从而恢复流。 如果我取消管道,这将解决问题。 这是我取消管道时的代码

const writableStream = createWriteStream(SOME_PATH);
get(SOME_URL, (res) => {
  res.pipe(writableStream);
  setTimeout(() => {
    res.unpipe(writableStream);
    res.pause();
  }, 2000);

  setTimeout(() => {
    res.pipe(writableStream);
    res.resume();
  }, 4000);
});

这实际上导致我的下载暂停。 但这会产生一个新问题。 调用res.unpipe() ,我仍然收到数据事件。 这意味着在调用res.unpipe()res.pause()之间的几毫秒内,我的一些数据被发送到res管道,但没有写入writableStream管道。 这以我下载的文件损坏而告终。

有没有办法解决这个问题? 我并没有接受取消管道的想法,这只是我能想出的唯一解决方案。

我正在考虑存储未通过管道传输到writableStreamres获得的数据,并在它们再次通过管道传输时手动将其传递给writableStream 这甚至可能吗? 如果没有,是否有其他方法可以在通过管道传输到可读流时暂停流?

我想到了。 我不确定为什么这个解决方案有效,但它对我有用。 我没有在暂停之前取消管道,而是在那里创建了一个用于pause和取消管道的侦听器。 此外,我还手动将res.readableFlowing设置为 false。 通过这两个添加,我能够在不破坏下载文件的情况下暂停和恢复。 这是实现

let isPaused = false;
const writableStream = createWriteStream(SOME_PATH);
get(SOME_URL, (res) => {
  res.pipe(writableStream);
  setTimeout(() => {
    isPaused = true;
    res.pause();
  }, 2000);

  setTimeout(() => {
    isPaused = false;
    res.pipe(writableStream);
    res.resume();
  }, 4000);

  res.on('pause', () => {
    // Add this flag because pause event gets called many times, and we only
    // want this code to happen when we call it manually
    if (isPaused) {
      res.unPipe(writableStream);
      res.readableFlowing = false;
    }
  });
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM