暂停 HTTP fetch() 请求

huangapple go评论126阅读模式
英文:

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

因此,你可以考虑几种方法:

  1. 将一个大的请求拆分成多个较小的请求。
  2. 使用 Range 标头接收多个部分,但然后必须自己将它们连接起来,而且服务器必须支持该标头。
  3. 也许你可以研究一下ReadableStream以确定它是否可以应用在这里(可能性较小)。
  4. 这个回答看起来也很有希望 暂停 HTTP fetch() 请求
英文:

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.

  1. split one big request into multiple smaller ones
  2. apply the Range header to receive multiple parts, but then you must join them yourself and the header must be supported.
  3. maybe you could read up on ReadableStream and whether it can be applied here (long shot)
  4. https://stackoverflow.com/a/75537289/2119863 looks promising too 暂停 HTTP fetch() 请求

huangapple
  • 本文由 发表于 2023年2月19日 04:12:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75496117.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定