一、请求取消:防止不必要的网络流量
当用户快速切换页面或重复触发请求时,未完成的请求会造成资源浪费。Axios 提供了两种取消机制:
1. 传统方案:CancelToken (适用于 v0.22.0 之前)
javascript
import axios from 'axios';
// 创建取消令牌源
const source = axios.CancelToken.source();
axios.get('/api/data', {
cancelToken: source.token
}).catch(thrown => {
if (axios.isCancel(thrown)) {
console.log('请求已取消', thrown.message);
}
});
// 取消请求(可传递原因)
source.cancel('用户导航离开页面');
2. 现代方案:AbortController (推荐)
go
const controller = new AbortController();
axios.get('/api/data', {
signal: controller.signal
}).catch(error => {
if (axios.isCancel(error)) {
console.log('取消原因:', error.message);
}
});
// 取消请求
controller.abort('操作被用户终止');
最佳实践场景:
- 页面切换时取消未完成请求
- 表单提交防重复点击
- 搜索框输入防抖处理
- 组件卸载时清理请求
二、进度监控:提升用户体验的关键
大文件传输场景中,进度反馈至关重要。Axios 通过 onUploadProgress
和 onDownloadProgress
提供实时进度更新:
上传进度监控
ini
const uploadFile = (file) => {
const formData = new FormData();
formData.append('file', file);
axios.post('/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
onUploadProgress: progressEvent => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
console.log(`上传进度: ${percentCompleted}%`);
// 更新UI进度条
progressBar.value = percentCompleted;
}
}).then(response => {
console.log('上传完成!');
});
};
下载进度监控
ini
axios.get('/large-file', {
responseType: 'blob',
onDownloadProgress: progressEvent => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
console.log(`下载进度: ${percentCompleted}%`);
// 显示下载进度通知
showNotification(`下载中... ${percentCompleted}%`);
}
}).then(response => {
// 创建文件下载链接
const url = URL.createObjectURL(response.data);
const a = document.createElement('a');
a.href = url;
a.download = 'file.zip';
document.body.appendChild(a);
a.click();
});
高级技巧:
ini
// 创建可复用的进度监控Hook
const useProgress = () => {
const [progress, setProgress] = useState(0);
const progressHandler = useCallback(progressEvent => {
const percent = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
setProgress(percent);
}, []);
return [progress, progressHandler];
};
// 在组件中使用
const [uploadProgress, onUploadProgress] = useProgress();
三、实战应用:结合取消与进度功能
scss
// 创建可取消的带进度监控请求
const fetchDataWithProgress = () => {
const controller = new AbortController();
axios.get('/api/large-data', {
signal: controller.signal,
onDownloadProgress: progressEvent => {
const percent = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
updateProgressBar(percent);
}
}).then(processData).catch(handleError);
// 返回取消方法
return () => controller.abort();
};
// 组件中使用
useEffect(() => {
const cancelRequest = fetchDataWithProgress();
return () => {
// 组件卸载时取消请求
cancelRequest();
};
}, []);
四、注意事项与优化建议
-
精度问题:
progressEvent.total
可能不可用(返回0)- 添加安全检查:
const total = progressEvent.total || 1;
-
性能优化:
javascript// 使用节流避免频繁渲染 onDownloadProgress: throttle(progressEvent => { // 更新逻辑 }, 200)
-
错误处理:
go.catch(error => { if (axios.isCancel(error)) { // 取消请求的特殊处理 } else { // 常规错误处理 } })
-
服务端支持:
- 确保服务器正确设置
Content-Length
头 - 分块传输编码可能影响进度准确性
- 确保服务器正确设置
结语
通过合理运用 Axios 的取消和进度监控功能,您可以显著提升应用性能与用户体验。关键要点:
- 使用 AbortController 管理现代取消逻辑
- onUploadProgress/onDownloadProgress 实现精细进度控制
- 结合 React/Vue 生命周期实现自动请求清理
- 大文件传输时提供可视化反馈
这些高级技巧将使您的应用在网络请求处理方面更加专业和高效,特别是在处理大文件传输和复杂用户交互场景时表现尤为突出。
拓展阅读:尝试将这些功能与 Axios 拦截器结合,创建全局请求管理解决方案,进一步提升代码复用性和可维护性。