29

I've read about cancelling fetch requests by using AbortController.abort(). Is there a way to start a request again without aborting it after calling this command?

For example, in this demo from MDN, once Cancel download has been clicked, clicking Download video will trigger the fetch again, but immediately abort it.

Is there a way to allow this request again without aborting it? So, in this case, how could you click Download video to begin the download, click Cancel download to cancel the download, and then click Download video again to start the download again? For example, if the user clicked Cancel download on accident...

jenwoodson
  • 373
  • 4
  • 9

3 Answers3

25

You can't.

An AbortController or its signal can not be reused nor reseted. If you need to "reset" it, you have to create a new AbortController instance and use that instead.

I think this is by design. Otherwise it could get messy e.g. if you hand over the controller or signal to some external library and suddenly they could remotely un-abort your internal state.

flori
  • 14,339
  • 4
  • 56
  • 63
8

For example, in this demo from MDN, once Cancel download has been clicked, clicking Download video will trigger the fetch again, but immediately abort it.

They fixed the example. After you click Cancel download you will be able to start a new download and cancel it again, over and over. In order to achieve that the Download button instantiate a new AbortController every time, so you get a fresh signal to abort every time:

downloadBtn.addEventListener('click', fetchVideo);

function fetchVideo() {
  controller = new AbortController();
  signal = controller.signal;
  // ...

So it's ok to instantiate new AbortControllers for each request that you may wish to cancel.

Marco Faustinelli
  • 3,734
  • 5
  • 30
  • 49
Rafael Renan Pacheco
  • 2,138
  • 21
  • 22
3

I know this might be kind of late, but I'm leaving this answer anyways in case someone needs it.

I don't know if this is the most optimal approach, but in order to keep doing fetch requests (with 'the same' signal) I had to create a new AbortController instance for each request.

In my case (all code being contained inside a class declaration), I deleted and created a new instance every time, like so:

class Foo Extends Bar {

    abort_controller_instance = false;

    constructor(params){
        super(params);
        this.resetOrStartAbortController();
    }

    resetOrStartAbortController(){
        if(this.abort_controller_instance){
            delete this.abort_controller_instance;
        }
        this.abort_controller_instance = new AbortController();
    }

    abortFetchRequest(){
        if(this.abort_controller_instance){
            this.abort_controller_instance.abort();
            this.resetOrStartAbortController();
        }
    }

    ...

}

Probably it's not the most elegant solution, but it works.

Regards!

JLeon
  • 61
  • 5