前端实现请求失败重试

1,028 阅读2分钟

最近写需求,产品提了一个小要求,前端发送了请求,失败了要重试,简单实现了一下,效果(视频转的gif,出来不知道为啥变慢了。。。)大致如下:

屏幕录制2023-04-26-23.09.45.gif

刚开始是想用 axios 的响应拦截器来着,可是自己尝试了一下,好像只能拿到最终结果,而不是请求失败之后,我能知道这是第几次请求失败,每次失败的原因是什么?因为有些失败的情况可能不允许再继续重试,所以对我这个需求而言,要能拿到每一次失败的结果。(ps:如果哪位大佬实现了,欢迎留言)

语言为 Vue3 + TypeScript

重试代码

async function retryRequest(maxRetries = 4, retryDelay = 2000): Promise<any> {
   let retries = 1
   while (retries <= maxRetries) {
      try {
        const response: any = await getArticles()
        return response.data
      } catch (error) {
        if (retries > 1) {
          errorText.value = `似乎出了点问题,正在重试 (${retries - 1}/${maxRetries - 1})`
        }
        
        retries++
        await new Promise((resolve) => setTimeout(resolve, retryDelay))
      }
   }

  throw new Error()

}

逻辑很简单,如果失败了就进行重试,成功了就直接返回结果

new Promise((resolve) => setTimeout(resolve, retryDelay))

这块相当于一个sleep函数

onMounted(async () => {
  try {
    const resp = await retryRequest()
    console.log(resp)
  } catch (error: any) {
   errorText.value = '请求失败,请稍后重试'
  }

})

在挂载结束后获取成功的返回值或者失败的信息,继而进行下一步处理,处理数据或者提示用户重试失败,让用户手动点击重试或者退出

加载动画代码

这块代码直接贴出来

<div class="loading"></div>

.loading {
  width: 30px;
  height: 30px;
  border: 2px solid #000;
  border-top-color: transparent;
  border-radius: 100%;
  animation: circle infinite 0.75s linear;
}

@keyframes circle {
  0% {
     transform: rotate(0);
  }
  
  100% {
    transform: rotate(360deg);
  }
}

想要了解更多不同loading动画的小伙伴可以点击 这里

结尾

导师review代码的时候推荐了 rxjs 的 方法,简单看了下,真的很优雅!后面有时间试试

截屏2023-04-26 22.55.28.png

截屏2023-04-26 22.55.20.png

RxJS - retry