react如何实现发起请求前取消上一个请求
使用 AbortController
在 React 中,可以通过 AbortController 取消正在进行的请求。AbortController 是现代浏览器提供的 API,用于中断请求。
创建一个 AbortController 实例,并将其 signal 属性传递给 fetch 请求。当需要取消请求时,调用 abort() 方法。

const controller = new AbortController();
fetch(url, { signal: controller.signal })
.then(response => response.json())
.catch(err => {
if (err.name === 'AbortError') {
console.log('Request was aborted');
}
});
// 取消请求
controller.abort();
结合 useEffect 清理函数
在 React 组件中,通常在 useEffect 中发起请求。利用 useEffect 的清理函数,可以在组件卸载或依赖项变化时取消未完成的请求。
useEffect(() => {
const controller = new AbortController();
const fetchData = async () => {
try {
const response = await fetch(url, { signal: controller.signal });
const data = await response.json();
setData(data);
} catch (err) {
if (err.name !== 'AbortError') {
console.error('Fetch error:', err);
}
}
};
fetchData();
return () => {
controller.abort();
};
}, [url]);
封装自定义 Hook
可以将取消请求的逻辑封装为自定义 Hook,便于复用。

function useFetch(url) {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
const controller = new AbortController();
const fetchData = async () => {
try {
const response = await fetch(url, { signal: controller.signal });
const result = await response.json();
setData(result);
} catch (err) {
if (err.name !== 'AbortError') {
setError(err);
}
}
};
fetchData();
return () => {
controller.abort();
};
}, [url]);
return { data, error };
}
结合 Axios 取消请求
如果使用 Axios,可以通过 CancelToken 实现类似功能。Axios 提供了更简洁的取消请求方式。
useEffect(() => {
const source = axios.CancelToken.source();
const fetchData = async () => {
try {
const response = await axios.get(url, {
cancelToken: source.token
});
setData(response.data);
} catch (err) {
if (!axios.isCancel(err)) {
console.error('Axios error:', err);
}
}
};
fetchData();
return () => {
source.cancel('Operation canceled by the user.');
};
}, [url]);
处理多个请求的场景
当需要处理多个请求时,可以为每个请求分配独立的 AbortController 或 CancelToken,确保取消操作只影响目标请求。
useEffect(() => {
const controllers = {};
const fetchData = async (url, key) => {
controllers[key] = new AbortController();
try {
const response = await fetch(url, { signal: controllers[key].signal });
const data = await response.json();
setData(prev => ({ ...prev, [key]: data }));
} catch (err) {
if (err.name !== 'AbortError') {
console.error(`Fetch error for ${key}:`, err);
}
}
};
fetchData('/api/data1', 'data1');
fetchData('/api/data2', 'data2');
return () => {
Object.values(controllers).forEach(controller => controller.abort());
};
}, []);
通过以上方法,可以在 React 应用中灵活地取消未完成的请求,避免潜在的内存泄漏或竞态条件问题。






