简体   繁体   中英

Aborted request using AbortController in React Redux app is aborted forever

I have a fetch service which sends requests to an API (using Redux-thunk). I want to cancel those requests sometimes (typically a user clicks on cancel button).

I use AbortController in this service and I call abort method of this controller in component's methods. For the first time, the request is aborted correctly but when I want to make this request again it is automatically aborted as well (even there is no request in Network tab of Chrome it immediately rejects).

// fetching service
const abortController = new AbortController();
const acSignal = abortController.signal;
export { abortController };

export default class FetchService {
    public static post(url: string): Promise<Response> {
        const requestOptions = {
            method: 'POST',
            body: ...
            signal: acSignal
        };
        return new Promise((resolve, reject) => {
            fetch(url, requestOptions)
                .then(resolve, reject);
        });
    }
}


// Component
import React from 'react';
import { abortController } from '../FetchService';
class Comp extends React.Component<{}, {}> {
   ...
   onCancelRequest = () => {
      // on cancel button click, abort request
      abortController.abort();
   }

   onButtonClick = () => {
      // initiate request
   }
}

onButtonClick -> requesting -> onCancelRequest -> request is aborted -> again onButtonClick -> request is aborted automatically (no other onCancelRequest)

Any tips what could be wrong? I just want to make the request again after it was aborted.

I was having exact same issue and resolved it by assigning new AbortController each time fetch is executed. Since I was dealing with fetch requests within redux thunks, I am not entirely sure about the exact solution in your case. But in the context of the provided snippet it might look like this:

// fetching service
let abortController;
export { abortController };

export default class FetchService {
    public static post(url: string): Promise<Response> {
        abortController = new AbortController();
        const requestOptions = {
            method: 'POST',
            body: ...
            signal: abortController.signal
        };
        return new Promise((resolve, reject) => {
            fetch(url, requestOptions)
                .then(resolve, reject);
        });
    }
}

However while this does the job, I am not sure if this approach entails any side effects like memory leaking or dangling abort controllers, and would very much appreciate input from more experienced developers. For instance, is there a way to reset existing controller instead of instantiating and assigning a new one?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM