0

I'm looking for a way to control repeated calls to the same webservice, in case of 2 identical remote requests, I want to abort the first one. Not sure yet if I can use AbortController. It seems if I call controller.abort(); before fetch I abort the subsequent call..

<button class="download"> fetch </button>
<button class="abort"> abort </button>
<script>
var controller = new AbortController();
var signal = controller.signal;

var downloadBtn = document.querySelector('.download');
var abortBtn = document.querySelector('.abort');

downloadBtn.addEventListener('click', fetchJson);

abortBtn.addEventListener('click', function() {
  controller.abort();
  console.log('Download aborted');
});

function fetchJson() {

  // TODO abort previous remote call here
  // controller.abort(); // won't work

  fetch("http://fakeapi.jsonparseronline.com/posts", {signal}).then( async response => {
    console.log(await response.json())
  }).catch(function(e) {
    console.error(e)
  })
}
</script>
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
alfredopacino
  • 2,979
  • 9
  • 42
  • 68

1 Answers1

1

You will have to create a new AbortController for each fetch, after you cancel the previous one. An AbortController's signal is set only once, similar to how you can resolve a promise only once, and it keeps the value afterwards. So if you don't renew your AbortController, the fetch will see an already-aborted signal.

let controller = new AbortController();

document.querySelector('.download').addEventListener('click', fetchJson);
document.querySelector('.abort').addEventListener('click', function() {
  controller.abort();
  console.log('Download aborted');
});

async function fetchJson() {
  controller.abort(); // abort previous fetch here

  controller = new AbortController(); // make new fetch abortable with a fresh AbortController
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  const signal = controller.signal;
  try {
    const response = await fetch("http://fakeapi.jsonparseronline.com/posts", {signal});
    console.log(await response.json());
  } catch() {
    console.error(e)
  }
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • that is what I tried and it seems it works. Thanks. Not sure I get why if I abort before `fetch` I'd expect the following request to be aborted.. – alfredopacino Apr 25 '21 at 15:00