[英]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
管道。 这以我下载的文件损坏而告终。
有没有办法解决这个问题? 我并没有接受取消管道的想法,这只是我能想出的唯一解决方案。
我正在考虑存储未通过管道传输到writableStream
时res
获得的数据,并在它们再次通过管道传输时手动将其传递给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.