• axios的请求中断和请求重试


    请求中断

    场景:
    	1、假如一个页面接口太多、或者当前网络太卡顿、这个时候跳往其他路由,
    	当前页面可以做的就是把请求中断掉(优化)
    	2、假如当前接口调取了第一页数据,又调去了第二页的数据,
    	当我们调取第二页数据时就需要把第一页数据的请求中断掉
    	(常见于在搜索大数据)
    	3、取消下载
    原理:
    	AbortController 接口表示一个控制器对象,允许你根据需要中止一个或多个 Web 请求
    技术:axios+vue3.0模拟
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    AbortController

    1. 实现
      	1、将中止控制器传递给 axios 的 调去接口的方法controller = new AbortController()
      	2、axios里面有定义标识的属性signal
      	3、点击事件:controller.abort()
      
      • 1
      • 2
      • 3
      <script setup lang="ts">
      import axios from 'axios'
      import { ref } from 'vue'
      
      const progress = ref(0) // 进度条百分比
      let controller: AbortController // 中止控制器
      
      // 中止下载
      const abortDownload = () => {
        if (controller) {
          controller.abort() // 使用 abort 方法中止下载
          console.log('中止下载')
        }
      }
      
      // 下载视频
      const fetchVideo = () => {
        controller = new AbortController() // 创建 AbortController
        axios({
          // 将中止控制器传递给 axios 的 get 方法
          method: 'GET',
          url: 'http://localhost:3000/video',
          signal: controller.signal,
          responseType: 'arraybuffer',
          onDownloadProgress: (progressEvent) => {
            // 计算进度百分比
            progress.value = Math.round((progressEvent.loaded / progressEvent.total!) * 100)
          }
        })
          .then((response) => {
            console.log('下载完成', response)
            // ✅ 保存下载的文件
            const { buffer } = new Uint8Array(response.data)
            const blob = new Blob([buffer], { type: 'application/octet-stream' })
            const link = document.createElement('a') // 创建链接元素
            link.href = URL.createObjectURL(blob) // 将 Blob 对象转换为 URL
            link.download = 'video.mp4' // 设置文件名
            link.click() // 模拟点击链接元素
          })
          .catch((err) => {
            if (axios.isCancel(err)) {
              console.log('下载被取消')
            } else if (err.name === 'AbortError') {
              console.log('下载被中止')
            } else {
              console.error(`下载错误:${err.message}`)
            }
          })
      }
      </script>
      
      <template>
        <div>
          <button class="download" @click="fetchVideo">下载视频</button>
          <button class="abort" @click="abortDownload">中止下载</button>
          <div class="progress-bar">
            <div class="progress" :style="{ width: progress + '%' }"></div>
            {{ progress }}%
          </div>
        </div>
      </template>
      
      <style scoped>
      .progress-bar {
        height: 20px;
        background-color: #eee;
        margin-top: 10px;
      }
      .progress {
        width: 0%;
        height: 100%;
        background-color: #4caf50;
        transition: width 0.2s linear;
      }
      </style>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75

    请求重试

    场景:
    	当用户访问我们的 Web 应用程序时,HTTP 请求可能会由于网络不稳定而失败,例如超时或网络异常。
    
    • 1
    • 2
    模拟 axios timeout: 2000,服务端加个延时3s。
    axios里面设置两个参数:{
    	retries: 3, // 设置重试次数为3次
      	retryDelay: 1000, // 设置重试的间隔时间
    }
    在响应拦截返回失败时进行重试:设置重试次数的参数,再次发送请求
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用 Axios 的拦截器拦截响应,则尝试再次发送请求,通过设置 retry 和 retryDelay 来控制重试请求的数量和每个请求之间的间隔。

    ```js
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    axios-retry 插件

    	插件可以更方便实现请求重试
    	npm install axios-retry
    
    • 1
    • 2
    导入以下数据就可以了
    // axios-retry 插件
    axiosRetry(request, {
      retries: 3, // 设置重试次数
      retryDelay: () => 500, // 设置重试延迟时间
      shouldResetTimeout: true, // 重置请求超时时间
      // error.code===ECONNABORTED表示请求超时了 ERR_NETWORK网络出错
      retryCondition: (error) => ['ECONNABORTED', 'ERR_NETWORK'].includes(error.code!), // 重试条件
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    <script setup lang="ts">
    import axios from 'axios'
    import axiosRetry from 'axios-retry'
    
    const request = axios.create({
      baseURL: 'http://localhost:3000',
      timeout: 2000,
    })
    
    // axios-retry 插件
    axiosRetry(request, {
      retries: 3, // 设置重试次数
      retryDelay: () => 500, // 设置重试延迟时间
      shouldResetTimeout: true, // 重置请求超时时间
      retryCondition: (error) => ['ECONNABORTED', 'ERR_NETWORK'].includes(error.code!), // 重试条件
    })
    
    // 请求中止控制器
    let controller: AbortController
    // --- 获取数据 ---
    const getData = async () => {
      // 请求控制器
      controller = new AbortController()
      const res = await request({
        method: 'GET',
        url: '/delay_3s_data',
        signal: controller.signal, // 添加请求中止标识
      })
      console.log('成功获取数据', res)
    }
    
    const stop = () => {
      // 中止网络请求
      controller.abort()
    }
    </script>
    
    <template>
      <h1>axios请求重试-axiosRetry</h1>
      <button @click="getData()">发送请求</button>
      <button @click="stop()">中止请求</button>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    推荐阅读

    axios的issues
    掘金-Axios 项目有哪些值得借鉴的地方

  • 相关阅读:
    【QT】创建第一个QT程序
    Linux - nm命令
    阿里面试官:乐观锁和悲观锁?可重入锁和Synchronized?
    总结709(bug集合)
    制作一个简单HTML抗疫逆行者网页作业(HTML+CSS)
    git commit规范
    Python的打包神器—Nuitka
    < Python全景系列-7 > 提升Python编程效率:模块与包全面解读
    UE5- c++ websocket里实现调用player里的方法
    八、cadence ic 5141 ——反相器原理图验证
  • 原文地址:https://blog.csdn.net/weixin_43909743/article/details/133796818