Axios 进阶指南:掌握请求取消与进度监控的艺术

一、请求取消:防止不必要的网络流量

当用户快速切换页面或重复触发请求时,未完成的请求会造成资源浪费。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 通过 onUploadProgressonDownloadProgress 提供实时进度更新:

上传进度监控

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(); 
  };
}, []);

四、注意事项与优化建议

  1. 精度问题

    • progressEvent.total 可能不可用(返回0)
    • 添加安全检查:const total = progressEvent.total || 1;
  2. 性能优化

    javascript 复制代码
    // 使用节流避免频繁渲染
    onDownloadProgress: throttle(progressEvent => {
      // 更新逻辑
    }, 200)
  3. 错误处理

    go 复制代码
    .catch(error => {
      if (axios.isCancel(error)) {
        // 取消请求的特殊处理
      } else {
        // 常规错误处理
      }
    })
  4. 服务端支持

    • 确保服务器正确设置 Content-Length
    • 分块传输编码可能影响进度准确性

结语

通过合理运用 Axios 的取消和进度监控功能,您可以显著提升应用性能与用户体验。关键要点:

  1. 使用 AbortController 管理现代取消逻辑
  2. onUploadProgress/onDownloadProgress 实现精细进度控制
  3. 结合 React/Vue 生命周期实现自动请求清理
  4. 大文件传输时提供可视化反馈

这些高级技巧将使您的应用在网络请求处理方面更加专业和高效,特别是在处理大文件传输和复杂用户交互场景时表现尤为突出。

拓展阅读:尝试将这些功能与 Axios 拦截器结合,创建全局请求管理解决方案,进一步提升代码复用性和可维护性。

相关推荐
Rasir3 分钟前
第四章:模块化设计与错误处理
前端
Xy9107 分钟前
App Trace功能实战:一键拉起、快速安装与免提写邀请码的应用实践
前端
前端的日常7 分钟前
前端如何优化音频和视频的加载性能?
前端
是晓晓吖9 分钟前
在Next.js中,ISR是如何工作的?(译文)
前端
FogLetter9 分钟前
智能前端之拍照识别单词(下):AI集成与交互优化
前端·aigc·openai
满分观察网友z10 分钟前
告别平庸!我用 picker-view 造的这两个选择器,让产品经理闭嘴了
前端
jqq66616 分钟前
Vue3脚手架实现(七、渲染eslint配置)
前端·javascript·vue.js
Mintopia18 分钟前
BVH:光线追踪里的空间管家
前端·javascript·计算机图形学
Mintopia24 分钟前
Three.js 射线拾取原理:像素世界的侦探故事
前端·javascript·计算机图形学
掘金安东尼43 分钟前
前端周刊第421期(2025年7月1日–7月6日)
前端·面试·github