取消请求方式
- XMLHttpRequest 的 abort()
javascript
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data');
xhr.send();
// 取消请求
xhr.abort();
- Fetch 配合 AbortController
javascript
const controller = new AbortController();
const signal = controller.signal;
fetch('https://api.example.com/data', { signal })
.then(response => response.json())
.catch(err => {
if (err.name === 'AbortError') {
console.log('请求被取消');
}
});
// 取消请求
controller.abort();
- Axios 取消请求
方式一:使用 CancelToken(旧版本)
javascript
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('https://api.example.com/data', {
cancelToken: source.token
});
// 取消请求
source.cancel('请求被用户取消');
方式二:使用 AbortController(新版本)
javascript
const controller = new AbortController();
axios.get('https://api.example.com/data', {
signal: controller.signal
});
// 取消请求
controller.abort();
- React Query 取消请求
javascript
const { refetch } = useQuery('key', fetchFn, {
enabled: false
});
// 组件卸载时自动取消
useEffect(() => {
const promise = refetch();
return () => {
// 取消请求
promise.cancel();
};
}, []);
- 应用场景
搜索防抖时取消上一次请求:
javascript
let controller = null;
const search = async (keyword) => {
// 取消之前的请求
if (controller) {
controller.abort();
}
// 创建新的 controller
controller = new AbortController();
try {
const response = await fetch(`/api/search?q=${keyword}`, {
signal: controller.signal
});
const data = await response.json();
return data;
} catch (err) {
if (err.name === 'AbortError') {
console.log('搜索请求被取消');
}
throw err;
}
};
组件卸载时取消请求:
javascript
function SearchComponent() {
useEffect(() => {
const controller = new AbortController();
const fetchData = async () => {
try {
const response = await fetch('/api/data', {
signal: controller.signal
});
const data = await response.json();
// 处理数据
} catch (err) {
if (err.name === 'AbortError') {
console.log('组件卸载,请求被取消');
}
}
};
fetchData();
// 清理函数
return () => {
controller.abort();
};
}, []);
return <div>搜索组件</div>;
}