0

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?

brillout
  • 7,804
  • 11
  • 72
  • 84
  • 4
    What effects should a pause have? For example, if a `fetch` is paused when the request is already sent to a remote server but the client hasn't received a response yet, what should the browser do when the client does receive a response? Should it keep the response in memory and wait for a `continue` call to trigger events? What if the `fetch` is paused during sending the request? The semantics of pausing a `fetch` is just not very clear to me. – Harlan Wei Feb 18 '23 at 20:24
  • 1
    Are you looking for [range requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests) or similar? Maybe this [article about streaming requests helps](https://developer.chrome.com/articles/fetch-streaming-requests/). Alternatively, you may be able to stitch something together with [XHR's `progress` event](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/progress_event). – Oskar Grosser Feb 18 '23 at 20:40
  • So what do you expect? People asked you questions and you have not responded. What does pausing do? What exactly is the use case? – epascarello Feb 21 '23 at 12:51
  • I'm curious in general and I've many different use cases in mind. That said, 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. – brillout Feb 21 '23 at 22:43
  • And apologies for not replying, and thanks for the answers so far. If pausing is possible (I wonder how servers handle the suggested answers), I'm quite surprised pausing isn't a common practice then. – brillout Feb 21 '23 at 22:48

3 Answers3

2

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.

xdumaine
  • 10,096
  • 6
  • 62
  • 103
  • The motivation for pausing is that all pending HTTP requests have already been fired: they should be paused in order to essentially increase "the network priority" of the new request that has higher/utmost priority. Now, such utmost priority request can happen anytime and when it happens is unpredictable, which means that a priority queue can't help. Btw., aborting instead of pausing would work equally well if the browser would cache the already received chunks but I don't think browser (can) do that. – brillout Feb 22 '23 at 15:18
1

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();
Surya R
  • 445
  • 2
  • 10
1

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 ;)
Unamata Sanatarai
  • 6,475
  • 3
  • 29
  • 51