axios 实现请求重试

前景提要:
ts 简易封装 axios,统一 API
实现在 config 中配置开关拦截器
请求重试的核心是可以重放请求,具体实现就是在 axios 中,拿到当前请求的 config 对象,再用 axios 实例,就能重放请求。
在无感刷新 token 中,当 access token 过期,使用 refresh token 刷新后,就需要再次对业务接口重放请求。
上面是一种请求重试的场景,一般情况下也不需要重试,所以我们这里讲的请求重试,指的都是请求网络错误的情况下需要重试。
比如断网了,然后重试。而不是因为接口返回 code 如 401 就重试。因为接口返回 401,从网络层面上讲,这是没有失败的,http 状态码是 200,返回 401 只是业务失败。
比起断网,更常见的网络错误下需要重试的是请求超时。
通过错误拦截器实现请求重试。整个请求过程是一个递归。
第一次请求失败,触发全局错误拦截,然后一路抛出错误,触发到重试的错误拦截器。判断还有重试次数后,拿到同一个实例重放请求。注意此时第一次请求并未结束,this.instance.request 方法依旧在等待结果。
如果请求依旧失败,则触发第二次请求的全局错误拦截,最后再次触发重试。如果第二次请求重试成功了,此时就拿到了请求结果。并且为了让结果最终被第一次请求捕获,需要在错误拦截器中抛出 fulfilled 状态的 promise 携带结果。
当请求次数用完,则错误拦截器继续抛出错误对象,触发第一次请求的 request 方法的 catch 代码块。宣告整个请求失败。
注意:
- 一定要以同一个 axios 实例重新发起请求,因为本质是递归,换个一个实例就拿不到重试成功后的请求结果了。
- 并且还需要在这个重试的错误拦截器中返回一个 fulfilled 状态的 promise,让第一次请求的实例方法捕获。
return Promise.resolve(res); 或 Promise.rejected(234); 都表示返回一个确定了状态的 promise,然后这个 promise 中携带了数据(就是参数)。
import httpRequest from "..";
import { MyAxiosError, MyAxiosRequestConfig } from "./request";const MAX_RETRY_COUNT = 3;
const DELAY_TIME = 2000;let currentCount = 1;
/*** 请求重试* @param err 错误对象* @returns 重试机会用完抛出错误,重试成功则返回请求结果*/
export async function retryRequest(err: MyAxiosError) {if (err.config.retry === false) throw err;if (err.message === "canceled") throw err; // 过滤手动取消请求的情况const config = err.config as MyAxiosRequestConfig;if (MAX_RETRY_COUNT >= currentCount && config) {console.log(`重试${currentCount}次...`);currentCount++;await sleep(DELAY_TIME);const res = await httpRequest.getInstance().request({ ...config });return Promise.resolve(res);}console.log("重试次数已用完...");currentCount = 0;throw err;
}/*** 延迟后续代码执行的工具函数,以同步代码阻塞的方式实现延迟:await sleep()* @param delayTime 延迟时间* @returns Promise*/
export function sleep(delayTime: number = 1000) {return new Promise(resolve => setTimeout(resolve, delayTime));
}相关文章:
axios 实现请求重试
前景提要: ts 简易封装 axios,统一 API 实现在 config 中配置开关拦截器 请求重试的核心是可以重放请求,具体实现就是在 axios 中,拿到当前请求的 config 对象,再用 axios 实例,就能重放请求。 在无感刷新…...
SSE加速随笔
Intel Intrinsics Guide 搞懂SSE 寄存器与指令数据细节 SSE指令集推出时,Intel公司在Pentium III CPU中增加了8个128位的SSE指令专用寄存器,称作XMM0到XMM7。这些XMM寄存器用于4个单精度浮点数运算的SIMD执行,并可以与MMX整数运算或x87浮点运…...
【TES720D】青翼科技基于复旦微的FMQL20S400全国产化ARM核心模
板卡概述 TES720D是一款基于上海复旦微电子FMQL20S400的全国产化核心模块。该核心模块将复旦微的FMQL20S400(兼容FMQL10S400)的最小系统集成在了一个50*70mm的核心板上,可以作为一个核心模块,进行功能性扩展,特别是用…...
arcgis删除细长图斑的方法
1、有一张图斑数据如下: 如上图,有很多细长的面要素,需要保留的仅是图中的块状要素。 2、首先要将被合并的要素进行拆分,具体拆分步骤如下: 将所有要素选中,点击高级编辑中的拆分按钮。 3、拆分后图斑就…...
Flutter笔记:Flutter的WidgetsBinding.instance的window属性
Flutter笔记 Flutter的WidgetsBinding.instance的window属性 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/det…...
element UI DatePicker 日期选择器 点击时间点可选限制范围前后十五天
<el-date-picker v-model"timeRange" type"datetimerange" align"right" :default-timedefaultTimevalue-format"yyyy-MM-dd HH:mm:dd" range-separator"至" start-placeholder"开始日期"end-placeholder"…...
【自用】vmware workstation建立主机window与虚拟机ubuntu之间的共享文件夹
1.在windows中建立1个文件夹 在vmware中设置为共享文件夹 参考博文: https://zhuanlan.zhihu.com/p/650638983 2.解决: (1)fuse: mountpoint is not empty (2)普通用户也能使用共享目录 参考博文&#x…...
【2023年MathorCup高校数学建模挑战赛-大数据竞赛】赛道A:基于计算机视觉的坑洼道路检测和识别 python 代码解析
【2023年MathorCup高校数学建模挑战赛-大数据竞赛】赛道A:基于计算机视觉的坑洼道路检测和识别 python 代码解析 1 题目 坑洼道路检测和识别是一种计算机视觉任务,旨在通过数字图像(通常是地表坑洼图像)识别出存在坑洼的道路。这…...
Mozilla Firefox 119 现已可供下载
Mozilla Firefox 119 开源网络浏览器现在可以下载了,是时候先看看它的新功能和改进了。 Firefox 119 改进了 Firefox View 功能,现在可以提供更多内容,如最近关闭的标签页和浏览历史,你可以按日期或网站排序,还支持查…...
What is 哈希?
哈希 前言:大一大二就一直听说哈希哈希,但一直都没有真正的概念:What is 哈希?这篇博客就浅浅聊一下作者认知中的哈希。 理解哈希 哈希(Hash)也可以称作散列,实质就是一种映射…...
在Photoshop中如何校正倾斜的图片
在Photoshop中如何校正倾斜的图片呢?今天就教大家如何操作。 将需要操作的图片拉到PS软件中,自动形成项目。 点击上方“滤镜”中的“镜头校正”。 进入“镜头校正”窗口,点击左侧的“拉直工具”。文章源自设计学徒自学网-http://www.sx1c.co…...
Maven第六章:Maven的自定义插件开发
Maven第六章:Maven的自定义插件开发 前言 maven不仅仅只是项目的依赖管理工具,其强大的核心来源自丰富的插件,可以说插件才是maven工具的灵魂。本篇文章将对如何自定义maven插件进行讲解,希望对各位读者有所帮助。 Maven插件开发的基本概念 Maven插件是由Maven构建工具本身…...
springboot 注入配置文件中的集合 List
在使用 springboot 开发时,例如你需要注入一个 url 白名单列表,你可能第一想到的写法是下面这样的: application.yml white.url-list:- /test/show1- /test/show2- /test/show3Slf4j RestController RequestMapping("/test") pub…...
springboot整合redis+lua实现getdel操作保证原子性
原始代码 脚本逻辑先获取redis的值,判断是否等于期望值。 条件成立则删除,不成立则返回0 if redis.call(get, KEYS[1]) ARGV[1] thenreturn redis.call(del, KEYS[1]) end return 0 测试代码 根据上面的逻辑加了测试, 在判断成功后等待5…...
win10系统nodejs的安装npm教程
1.在官网下载nodejs,https://nodejs.org/en 2,双击nodejs的安装包 3,点击 next 4,勾选I accpet the terms in…… 5,第4步点击next进入配置安装路径界面 6,点击next,选中Add to PATH ,旁边…...
C语言assert函数:什么是“assert”函数
我一直在学习 OpenCV 教程,遇到了assert函数;它做什么? assert将终止程序(通常带有引用 assert 语句的消息),如果其参数为 false。它通常在调试过程中使用,以使程序在发生意外情况时更明显地失败。 例如&…...
R语言绘图-5-条形图(修改坐标轴以及图例等)
0. 说明: 1. 绘制条形图; 2. 添加文本并调整位置; 3. 调整x轴刻度的字体、角度及颜色; 4. 在导出pdf时,如果没有字体,该怎么解决问题; 1. 结果: 2. 代码: library(ggp…...
uniapp自定义权限菜单,动态tabbar
已封装为组件,亲测4个菜单项目可以切换, 以下为示例,根据Storage 中 userType 的 值,判断权限菜单 <template><view class"tab-bar pb10"><view class"tabli" v-for"(tab, index) in ta…...
ubuntu20.04配置解压版mysql5.7
目录 1.创建mysql 用户组和用户2.下载 MySQL 5.7 解压版3.解压 MySQL 文件4.将 MySQL 移动到适当的目录5.更改mysql目录所属的用户组和用户,以及权限6.进入mysql/bin/目录,安装初始化7.编辑/etc/mysql/my.cnf配置文件8.启动 MySQL 服务:9.建立…...
【js】vue获取document.getElementById(a)为null
需求 在菜单A页面点击某个元素携带id跳转到B详情页面,B页面获取该id元素的offsetTop, 并自动滚动到该元素处 问题 跳转到B详情页面, 在mounted获取到document.getElementById(a)为null, 因为整个详情页面是从后端获取来渲染的数据, 因此此时dom元素还未渲染出来,…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
6.9-QT模拟计算器
源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...
解析“道作为序位生成器”的核心原理
解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制,重点解析"道作为序位生成器"的核心原理与实现框架: 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...
Java设计模式:责任链模式
一、什么是责任链模式? 责任链模式(Chain of Responsibility Pattern) 是一种 行为型设计模式,它通过将请求沿着一条处理链传递,直到某个对象处理它为止。这种模式的核心思想是 解耦请求的发送者和接收者,…...
智能体革命:企业如何构建自主决策的AI代理?
OpenAI智能代理构建实用指南详解 随着大型语言模型(LLM)在推理、多模态理解和工具调用能力上的进步,智能代理(Agents)成为自动化领域的新突破。与传统软件仅帮助用户自动化流程不同,智能代理能够自主执行工…...
