英文:
Pause HTTP fetch() requests
问题
如在Stack Overflow - 如何取消HTTP fetch()请求?中所示,我们现在可以使用AbortController来中止fetch()
请求。
与中止fetch()
请求不同,我只想将其暂停,然后稍后恢复。这是可能的吗?
英文:
As seen in Stack Overflow - How do I cancel an HTTP fetch() request?, we can nowadays abort a fetch()
request using AbortController.
Instead of aborting a fetch()
request, I'd like to merely pause it and resume it later. Is it possible?
答案1
得分: 2
答案是 "不可能"。
你可以实现类似优先级队列的东西(可以手动实现或使用一些现有的库,这超出了这个问题的范围),以便你的应用程序在处理任何高优先级结果之后处理已完成的 fetch
承诺的结果。
英文:
To answer the root of your question:
> Instead of aborting a fetch() request, I'd like to merely pause it and resume it later. Is it possible?
The answer is "no, it is not possible."
That said, to answer your comment:
> the main use case is some event happening that is of utmost priority and all other pending requests should be paused. The other requests should resume once the urgent request is finished.
You can probably implement something like a priority queue (either manually or via some existing library, that's outside the scope of this question), such that your application handles the result of the completed fetch
promise after any higher priority results are handled.
答案2
得分: 1
除了使用AbortController之外,从其他JavaScript方法暂停和恢复HTTP请求实际上是不可能的。
i) 我们可以在一个Promise内使用fetch()调用,实际上可以决定是拒绝还是解决请求,无论您是否想要暂停或拒绝请求。但这不支持恢复功能。
ii) AbortController执行类似暂停请求(中止正在进行的请求)的功能,然后再次使用相同的控制器发出请求
const controller = new AbortController();
const signal = controller.signal;
fetch(url, {..., signal: signal}).then(response => ...);
要暂停:
controller.abort()
要恢复:fetch(url, {..., signal: signal}).then(response => ...);
基本上是使用相同的控制器对象再次发出一个请求。
有关更多数据,请参考这里:https://developer.mozilla.org/en-US/docs/Web/API/AbortController
iii) 如果您正在寻找通过HTTP发生的流程暂停/恢复,您可以使用我在这里找到的示例方法:https://gist.github.com/Grigore147/4611134
var Http = require('http');
var Fs = require('fs');
// 一些指向大型视频文件的URL
var url = 'url';
var path = 'save_path';
var downloaded = 0;
var percents = 0;
var size = 0;
var request = Http.request(url, function(response) {
size = parseInt(response.headers['content-length']);
response.on('data', function(chunk) {
downloaded += chunk.length;
percents = parseInt((downloaded / size) * 100);
console.log(percents + '%', downloaded + '/' + size);
});
response.on('error', function(error) {
console.log(error);
});
response.pipe(Fs.createWriteStream(path));
setTimeout(function() {
response.pause();
console.log('stream paused');
setTimeout(function() {
response.resume();
console.log('stream resumed');
}, 5000);
}, 5000);
}).end();
这段代码演示了如何通过HTTP暂停和恢复流。
英文:
It is Actually not possible to pause and resume the HTTP request from the other js methods except the AbortController,
i) we can use fetch() call inside a promise and we can actually decide whether to reject or resolve the request whether you want to pause or reject the requests. this will not support u the resume feature.
ii) The AbortController does the similar functionality of pausing the requests (aborting the on going request) and upon using the same controller make the requests again
const controller = new AbortController();
const signal = controller.signal;
fetch(url, {..., signal: signal}).then(response => ...);
To pause :
controller.abort()
To resume: fetch(url, {..., signal: signal}).then(response => ...);
basically we are making one more request using the same controller object used fetch again.
refer here for more data : https://developer.mozilla.org/en-US/docs/Web/API/AbortController
iii) if your are looking for stream process pause / resume which is happening through http you can use the below sample method i found here : https://gist.github.com/Grigore147/4611134
var Http = require('http');
var Fs = require('fs');
// some url to big video file
var url = 'url';
var path = 'save_path';
var downloaded = 0;
var percents = 0;
var size = 0;
var request = Http.request(url, function(response) {
size = parseInt(response.headers['content-length']);
response.on('data', function(chunk) {
downloaded += chunk.length;
percents = parseInt((downloaded / size) * 100);
console.log(percents +'%', downloaded +'/'+size);
});
response.on('error', function(error) {
console.log(error);
});
response.pipe(Fs.createWriteStream(path));
setTimeout(function() {
response.pause(); console.log('stream paused');
setTimeout(function() {
response.resume(); console.log('stream resumed');
}, 5000);
}, 5000);
}).end();
答案3
得分: 1
不可能暂停 fetch()
。AbortController
用于取消操作,而不是暂停。由于它会取消,所以无法恢复。这就好像用刀切断一根绳子。在这个比喻中,Cancel == cut
。
因此,你可以考虑几种方法:
- 将一个大的请求拆分成多个较小的请求。
- 使用
Range
标头接收多个部分,但然后必须自己将它们连接起来,而且服务器必须支持该标头。 - 也许你可以研究一下ReadableStream以确定它是否可以应用在这里(可能性较小)。
- 这个回答看起来也很有希望
英文:
It is not possible to pause a fetch()
. The AbortController
is there to cancel, not pause. And since it will cancel, it cannot be resumed. It's like taking a knife to a string. Cancel == cut
in this analogy.
So, there are several approaches you might consider.
- split one big request into multiple smaller ones
- apply the
Range
header to receive multiple parts, but then you must join them yourself and the header must be supported. - maybe you could read up on ReadableStream and whether it can be applied here (long shot)
- https://stackoverflow.com/a/75537289/2119863 looks promising too
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论