refactor(api): implement abort signal handling in API requests across multiple components to improve cancellation of ongoing requests and prevent memory leaks
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 2m12s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 2m12s
This commit is contained in:
@@ -86,14 +86,25 @@ function DomainsNewManager() {
|
||||
// Справочник community для подсказок
|
||||
const [communities, setCommunities] = useState([]);
|
||||
useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
(async () => {
|
||||
try {
|
||||
const res = await api.get(`/communities`);
|
||||
const res = await api.get(`/communities`, { signal });
|
||||
setCommunities(Array.isArray(res.data) ? res.data : []);
|
||||
} catch (e) {
|
||||
// тихо игнорируем
|
||||
if (e?.name === 'CanceledError' || e?.name === 'AbortError' || e?.code === 'ERR_CANCELED') return;
|
||||
}
|
||||
})();
|
||||
(async () => {
|
||||
try {
|
||||
const r = await api.get('/ws/url', { signal });
|
||||
setWsUrl(String(r.data?.url || ''));
|
||||
} catch (e) {
|
||||
if (e?.name === 'CanceledError' || e?.name === 'AbortError' || e?.code === 'ERR_CANCELED') return;
|
||||
}
|
||||
})();
|
||||
return () => controller.abort();
|
||||
}, []);
|
||||
|
||||
const renderCommunityBadge = (value) => (<CommunityBadge value={value} communities={communities} />);
|
||||
@@ -110,14 +121,11 @@ function DomainsNewManager() {
|
||||
const [wsOpen, setWsOpen] = useState(false);
|
||||
const [wsUrl, setWsUrl] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
(async () => { try { const r = await api.get('/ws/url'); setWsUrl(String(r.data?.url || '')); } catch {} })();
|
||||
}, []);
|
||||
|
||||
const fetchItems = async () => {
|
||||
const fetchItems = async (abortSignal) => {
|
||||
setLoading(true);
|
||||
const opts = abortSignal ? { signal: abortSignal } : {};
|
||||
try {
|
||||
const response = await api.get(`/domains-new`, { params: { offset: 0, limit: 0, format: 'std' } });
|
||||
const response = await api.get(`/domains-new`, { params: { offset: 0, limit: 0, format: 'std' }, ...opts });
|
||||
const payload = Array.isArray(response.data?.items) ? response.data.items : [];
|
||||
const total = payload.length;
|
||||
setItems(payload);
|
||||
@@ -129,6 +137,7 @@ function DomainsNewManager() {
|
||||
setContentLength(typeof lengthHeader !== 'undefined' ? Number(lengthHeader) : null);
|
||||
setError('');
|
||||
} catch (error) {
|
||||
if (error?.name === 'CanceledError' || error?.name === 'AbortError' || error?.code === 'ERR_CANCELED') return;
|
||||
console.error('Error fetching domains-new:', error);
|
||||
setError('Не удалось загрузить домены. Проверьте, запущен ли бэкенд.');
|
||||
} finally {
|
||||
@@ -136,8 +145,14 @@ function DomainsNewManager() {
|
||||
}
|
||||
};
|
||||
|
||||
// Подгрузка при изменении страницы/поиска/фильтра
|
||||
useEffect(() => { if (!didInit.current) { didInit.current = true; fetchItems(); } }, []);
|
||||
useEffect(() => {
|
||||
if (!didInit.current) {
|
||||
didInit.current = true;
|
||||
const controller = new AbortController();
|
||||
fetchItems(controller.signal);
|
||||
return () => controller.abort();
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleAddItem = (item) => {
|
||||
// Если item передан (из модалки), используем его, иначе из state (старый способ)
|
||||
|
||||
Reference in New Issue
Block a user