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));
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/116348.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

iOS App Store上传项目报错 缺少隐私政策网址(URL)解决方法

iOS App Store上传项目报错 缺少隐私政策网址(URL)解决方法 一、问题如下图所示: 二、解决办法:使用Google浏览器(翻译成中文)直接打开该网址 https://www.freeprivacypolicy.com/free-privacy-policy-generator.php 按照要求…

面试10000次依然会问的【ReentrantLock】,你还不会?

引言 在并发编程的世界中,ReentrantLock扮演着至关重要的角色。它是一个实现了重入特性的互斥锁,提供了比synchronized关键字更加灵活的锁定机制。ReentrantLock属于java.util.concurrent.locks包,是Java并发API的一部分。 与传统的synchro…

ActiveMQ、RabbitMQ、RocketMQ、Kafka介绍

一、消息中间件的使用场景 消息中间件的使用场景总结就是六个字:解耦、异步、削峰 1.解耦 如果我方系统A要与三方B系统进行数据对接,推送系统人员信息,通常我们会使用接口开发来进行。但是如果运维期间B系统进行了调整,或者推送过…

【Redis】Redis在Linux与windows上的安装基本操作语法

一、Redis简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。 Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再…

突破性技术!开源多模态模型—MiniGPT-5

多模态生成一直是OpenAI、微软、百度等科技巨头的重要研究领域,但如何实现连贯的文本和相关图像是一个棘手的难题。 为了突破技术瓶颈,加州大学圣克鲁斯分校研发了MiniGPT-5模型,并提出了全新技术概念“Generative Vokens "&#xff0c…

mysql之基础语句

数据库的列类型 int:整型 用于定义整数类型的数据 float:单精度浮点4字节32位 准确表示到小数点后六位 double:双精度浮点8字节64位 char:固定长度的字符类 用于定义字符类型数据&…

Rust编程基础核心之所有权(下)

1.变量与数据交互方式之二: 克隆 在上一节中, 我们讨论了变量与数据交互的第一种方式: 移动, 本节将介绍第二种方式:克隆。 如果我们 确实 需要深度复制 String 中堆上的数据,而不仅仅是栈上的数据,可以使用一个叫做 clone 的通用函数。 看下面的代码…

Hybrid App(原生+H5)开发

介绍 市面上主流的hybrid app框架主要有 React Native:由FaceBook开发,使用JavaScript和React来构建原生应用程序Flutter:由Google开发,使用Dart语言。Flutter使用自己的渲染引擎Ionic:基于 Web 技术(HTM…

网络安全(网络安全)小白自学

想自学网络安全(黑客技术)首先你得了解什么是网络安全!什么是黑客! 网络安全可以基于攻击和防御视角来分类,我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术,而“蓝队”、“安全运营”、“安全…

一、Hadoop初始化配置(final+ubuntu保姆级教程)

1、配置虚拟机 三台虚拟机,分别为node1、node2、node3,内存分别为4G、2G、2G,现存最好为(>40G),如下: 2、修改主机名 分别打开三台虚拟机,root用户输入一下命令: no…

蓝桥杯官网填空题(方格填数)

题目描述 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。 在 2 行 5 列的格子中填入 1 到 10 的数字。 要求: 相邻的格子中的数,右边的大于左边的,下边的大于上边的。 如下图所示的 …

鸿蒙LiteOs读源码教程+向LiteOS中添加一个简单的基于线程运行时的短作业优先调度策略

一、鸿蒙Liteos读源码教程 鸿蒙的源码是放在openharmony文件夹下,openharmony下的kernel文件夹存放操作系统内核的相关代码和实现。 内核是操作系统的核心部分,所以像负责:资源管理、任务调度、内存管理、设备驱动、进程通信的源码都可以在…

Qt学习:图形视图框架的使用

文章目录 前言一、场景、视图和图形项的介绍二、图形视图框架的坐标系统三、图形视图框架的事件处理四、示例完整代码五、QtCreator官方示例总结 前言 近期重温了一下Qt中的图形视图框架,这里将所学习的内容进行记录总结。这个框架提供了一个基于图形项的模型视图编…

MySQL InnoDB数据存储结构

1. 数据库的存储结构:页 索引结构给我们提供了高效的索引方式,不过索引信息以及数据记录都是保存在文件上的,确切说是存储在页结构中。另一方面,索引是在存储引擎中实现的,MySQL服务器上的存储引擎负责对表中数据的读…

【漏洞复现】Fastjson_1.2.47_rce

感谢互联网提供分享知识与智慧,在法治的社会里,请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞检测3、漏洞验证 1.5、深度利用1、反弹Shell 说明内容漏洞编号漏洞名称Fastjson_1.2.47_远程执行漏…

【HarmonyOS】服务卡片 API6 JSUI跳转不同页面并携带参数

【关键字】 服务卡片、卡片跳转不同页面、卡片跳转页面携带参数 【写在前面】 本篇文章主要介绍开发服务卡片时,如何实现卡片点击跳转不同页面,并携带动态参数到js页面。在此篇文章“服务卡片 API6 JSUI跳转不同页面”中说明了如果跳转不同页面&#xf…

Py之auto-gptq:auto-gptq的简介、安装、使用方法之详细攻略

Py之auto-gptq:auto-gptq的简介、安装、使用方法之详细攻略 目录 auto-gptq的简介 1、版本更新历史 2、性能对比 推理速度 困惑度(PPL) 3、支持的模型 3、支持的评估任务 auto-gptq的安装 auto-gptq的使用方法 1、基础用法 (1)、量…

2023-11-04:用go语言,如果n = 1,打印 1*** 如果n = 2,打印 1*** 3*** 2*** 如果n = 3,打印

2023-11-04:用go语言,如果n 1,打印 1*** 如果n 2,打印 1***3*** 2*** 如果n 3,打印 1***3*** 2***4*** 5*** 6*** 如果n 4,打印 1***3*** 2***4*** 5*** 6***10** 9*** 8*** 7*** 输入…

立创eda专业版学习笔记(8)(运行模式)

以前没注意过这个问题,我有2台电脑,都能登录eda专业版,但是一台是全在线模式,另外一台是半离线模式,虽然是同一个账号,但是打开里面的工程会发现,两边的工程完全不同,因为一台的工程…

shell script 的默认变量$0,$1,$2...,参数偏移的shift

简单来说,在scirpt脚本里面,$0表示文件名,$1表示第一个参数,以此类推,还有 $# 后面接参数的个数 $ 代表"$1","$2","$3",每个都是独立的,用双引号括起来 $* 代…