温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Axios怎么实现请求重试

发布时间:2021-07-06 10:59:03 来源:亿速云 阅读:511 作者:chen 栏目:互联网科技

本篇内容介绍了“Axios怎么实现请求重试”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一、拦截器实现请求重试的方案

Axios 是一个基于 Promise 的 HTTP 客户端,而 HTTP 协议是基于请求和响应:

Axios怎么实现请求重试

所以 Axios 提供了 请求拦截器和响应拦截器 来分别处理请求和响应,它们的作用如下:

  • 请求拦截器:该类拦截器的作用是在请求发送前统一执行某些操作,比如在请求头中添加 token 字段。

  • 响应拦截器:该类拦截器的作用是在接收到服务器响应后统一执行某些操作,比如发现响应状态码为 401 时,自动跳转到登录页。

在 Axios 中设置拦截器很简单,通过 axios.interceptors.request 和 axios.interceptors.response  对象提供的 use 方法,就可以分别设置请求拦截器和响应拦截器:

export interface AxiosInstance {   interceptors: {     request: AxiosInterceptorManager<AxiosRequestConfig>;     response: AxiosInterceptorManager<AxiosResponse>;   }; }  export interface AxiosInterceptorManager<V> {   use(onFulfilled?: (value: V) => V | Promise<V>,      onRejected?: (error: any) => any): number;   eject(id: number): void; }

对于请求重试的功能来说,我们希望让用户不仅能够设置重试次数,而且可以设置重试延时时间。当请求失败的时候,若该请求的配置对象配置了重试次数,而 Axios  就会重新发起请求进行重试操作。为了能够全局进行请求重试,接下来我们在响应拦截器上来实现请求重试功能,具体代码如下所示:

axios.interceptors.response.use(null, (err) => {   let config = err.config;   if (!config || !config.retryTimes) return Promise.reject(err);   const { __retryCount = 0, retryDelay = 300, retryTimes } = config;   // 在请求对象上设置重试次数   config.__retryCount = __retryCount;   // 判断是否超过了重试次数   if (__retryCount >= retryTimes) {     return Promise.reject(err);   }   // 增加重试次数   config.__retryCount++;   // 延时处理   const delay = new Promise((resolve) => {     setTimeout(() => {       resolve();     }, retryDelay);   });   // 重新发起请求   return delay.then(function () {     return axios(config);   }); });

以上的代码并不会复杂,对应的处理流程如下图所示:

Axios怎么实现请求重试

介绍完如何使用拦截器实现请求重试的功能之后,下面阿宝哥来介绍适配器实现请求重试的方案。

二、适配器实现请求重试的方案

Axios 引入了适配器,使得它可以同时支持浏览器和 Node.js 环境。对于浏览器环境来说,它通过封装  XMLHttpRequest API 来发送 HTTP 请求,而对于 Node.js 环境来说,它通过封装 Node.js 内置的 http 和 https  模块来发送 HTTP 请求。

在 Axios 如何缓存请求数据? 这篇文章中,阿宝哥介绍了如何通过增强默认的 Axios  适配器,来实现缓存请求数据的功能。同样,采用类似的思路,我们也可以通过增强默认的 Axios 适配器来实现请求重试的功能。

在介绍如何增强默认适配器之前,我们先来看一下 Axios 内置的 xhrAdapter 适配器,它被定义在 lib/adapters/xhr.js  文件中:

// lib/adapters/xhr.js module.exports = function xhrAdapter(config) {   return new Promise(function dispatchXhrRequest(resolve, reject) {     var requestData = config.data;     var requestHeaders = config.headers;      var request = new XMLHttpRequest();     // 省略大部分代码     var fullPath = buildFullPath(config.baseURL, config.url);     request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);     // Set the request timeout in MS     request.timeout = config.timeout;      // Listen for ready state     request.onreadystatechange = function handleLoad() { ... }      // Send the request     request.send(requestData);   }); };

很明显 xhrAdapter 适配器是一个函数对象,它接收一个 config 参数并返回一个 Promise 对象。而在 xhrAdapter  适配器内部,最终会使用 XMLHttpRequest API 来发送 HTTP 请求。为了实现请求重试的功能,我们就可以考虑通过高阶函数来增强  xhrAdapter适配器的功能。

2.1 定义 retryAdapterEnhancer 函数

为了让用户能够更灵活地控制请求重试的功能,我们定义了一个 retryAdapterEnhancer函数,该函数支持两个参数:

  • adapter:预增强的 Axios 适配器对象;

  • options:缓存配置对象,该对象支持 2 个属性,分别用于配置不同的功能:

  • times:全局设置请求重试的次数;

  • delay:全局设置请求延迟的时间,单位是 ms。

了解完 retryAdapterEnhancer 函数的参数之后,我们来看一下该函数的具体实现:

function retryAdapterEnhancer(adapter, options) {   const { times = 0, delay = 300 } = options;    return async (config) => {     const { retryTimes = times, retryDelay = delay } = config;     let __retryCount = 0;     const request = async () => {       try {         return await adapter(config);       } catch (err) {         // 判断是否进行重试         if (!retryTimes || __retryCount >= retryTimes) {           return Promise.reject(err);         }         __retryCount++; // 增加重试次数         // 延时处理         const delay = new Promise((resolve) => {           setTimeout(() => {             resolve();           }, retryDelay);          });          // 重新发起请求          return delay.then(() => {            return request();          });         }       };    return request();   }; }

以上的代码并不会复杂,核心的处理逻辑如下图所示:

Axios怎么实现请求重试

2.2 使用 retryAdapterEnhancer 函数

2.2.1 创建 Axios 对象并配置 adapter 选项

const http = axios.create({   baseURL: "http://localhost:3000/",   adapter: retryAdapterEnhancer(axios.defaults.adapter, {     retryDelay: 1000,   }), });

2.2.2 使用 http 对象发送请求

// 请求失败不重试 function requestWithoutRetry() {   http.get("/users"); }  // 请求失败重试 function requestWithRetry() {   http.get("/users", { retryTimes: 2 }); }

好了,如何通过增强 xhrAdapter 适配器来实现 Axios  请求重试的功能已经介绍完了。由于完整的示例代码内容比较多,阿宝哥就不放具体的代码了。感兴趣的小伙伴,可以访问以下地址浏览示例代码。

  • 完整的示例代码:

  • https://gist.github.com/semlinker/979ebc659abacea7aa6c0c44af070afe

这里我们来看一下 Axios 实现请求重试示例的运行结果:

Axios怎么实现请求重试

三、总结

本文介绍了在 Axios 中如何实现请求重试,基于文中定义的 retryAdapterEnhancer  函数或响应拦截器,你可以轻松地扩展请求重试的功能。

Axios 是一个很优秀的开源项目,里面有很多值得我们学习与借鉴的地方。如果你对 Axios 内部 HTTP 拦截器的设计与实现、HTTP  适配器的设计与实现及如何防御 CSRF 攻击感兴趣的话,可以阅读 77.9K 的 Axios 项目有哪些值得借鉴的地方 这篇文章。

“Axios怎么实现请求重试”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI