#javascript #reactjs #redux
#javascript #reactjs #сокращение
Вопрос:
У меня есть служба выборки, которая отправляет запросы в API (используя Redux-thunk). Иногда я хочу отменить эти запросы (обычно пользователь нажимает на кнопку отмены).
Я использую AbortController в этой службе и вызываю метод прерывания этого контроллера в методах компонента. В первый раз запрос прерывается корректно, но когда я хочу сделать этот запрос снова, он также автоматически прерывается (даже если на вкладке Сети Chrome нет запроса, он немедленно отклоняется).
// 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 -> запрос -> onCancelRequest -> запрос прерван -> снова onButtonClick -> запрос прерван автоматически (другого запроса onCancel нет)
Любые советы, что может быть не так? Я просто хочу снова выполнить запрос после того, как он был прерван.
Комментарии:
1. Я бы переключился на использование Axios и сохранил токен отмены, чтобы вы могли отменить их, если будет выполнено определенное действие. Функция выборки не позволяет отменять запросы «из коробки».
Ответ №1:
У меня была точно такая же проблема, и я решил ее, назначая новую AbortController
при каждом fetch
выполнении. Поскольку я имел дело с fetch
запросами в redux thunks, я не совсем уверен в точном решении в вашем случае. Но в контексте предоставленного фрагмента это может выглядеть следующим образом:
// 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);
});
}
}
Однако, хотя это и выполняет свою работу, я не уверен, влечет ли этот подход за собой какие-либо побочные эффекты, такие как утечка памяти или зависающие контроллеры прерывания, и был бы очень признателен за информацию от более опытных разработчиков. Например, есть ли способ сбросить существующий контроллер вместо создания экземпляра и назначения нового?