管道传输到可写流时暂停可读流
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 下载时,这不会暂停。
我认为这是因为我的可读流通过管道传输到可写流,而可写流正在请求更多数据,从而恢复流。如果我取消管道,这将解决问题。这是我 unpipe
时的代码
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
管道。这以我下载的文件损坏而告终。
有什么办法可以解决这个问题吗?我不接受拆管道的想法,这只是我能想到的唯一解决方案。
我正在考虑存储 res
在未通过管道传输到 writableStream
时获取的数据,并在它们再次通过管道传输时手动将其传递给 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;
}
});
});
我有一个可读的流,我想暂停。它通过管道传输到可写流。我的代码看起来像这样
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 下载时,这不会暂停。
我认为这是因为我的可读流通过管道传输到可写流,而可写流正在请求更多数据,从而恢复流。如果我取消管道,这将解决问题。这是我 unpipe
时的代码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
管道。这以我下载的文件损坏而告终。
有什么办法可以解决这个问题吗?我不接受拆管道的想法,这只是我能想到的唯一解决方案。
我正在考虑存储 res
在未通过管道传输到 writableStream
时获取的数据,并在它们再次通过管道传输时手动将其传递给 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;
}
});
});