首页 > 其他分享 >axios请求失败、请求超时重新发送请求

axios请求失败、请求超时重新发送请求

时间:2023-11-17 16:23:16浏览次数:35  
标签:axios return 请求 发送 Promise error 超时 config

一、 axios 重新发送请求基础版(所有的请求错误,不论是请求超时还是接口请求出错都会进行重试)

以下是一个完整的文件,看懂了的话 axios 重试请求也就基本会了,不会的话直接复制到项目里,也可以直接调用使用。

  1. 创建一个 axios 实例,并在实例中设置请求超时时间 timeout、重试请求次数 retry、请求间隔 retryDelay。
  2. 为实例设置相应拦截器,在请求返回错误的时候对错误做处理。
  3. 如果请求次数已经达到设置好的请求次数,不再发送请求,返回最终的错误信息;

如果请求次数还没有达到设置好的请求次数,就在停留 retryDelay(请求间隔)时间后,再次发起请求

import axios from "axios";
//创建一个axios实例
const requests = axios.create({
  timeout: 5 * 1000, //请求超时时间(5秒后还未接收到数据,就需要再次发送请求)
  retry: 3, //设置全局重试请求次数(最多重试几次请求)
  retryDelay: 1000, //设置全局请求间隔
});

//响应拦截器
requests.interceptors.response.use(
  (res) => {
    return Promise.resolve(res.data);
  },
  (error) => {
    //console.log(error);
    //超时处理 error.config是一个对象,包含上方create中设置的三个参数
    var config = error.config;
    if (!config || !config.retry) return Promise.reject(error);

    // __retryCount用来记录当前是第几次发送请求
    config.__retryCount = config.__retryCount || 0;

    // 如果当前发送的请求大于等于设置好的请求次数时,不再发送请求,返回最终的错误信息
    if (config.__retryCount >= config.retry) {
      return Promise.reject(error);
    }

    // 记录请求次数+1
    config.__retryCount += 1;

    // 设置请求间隔 在发送下一次请求之前停留一段时间,时间为上方设置好的请求间隔时间
    var backoff = new Promise(function (resolve) {
      setTimeout(function () {
        resolve();
      }, config.retryDelay || 1);
    });

    // 再次发送请求
    return backoff.then(function () {
      return requests(config);
    });
  }
);

export default requests;
  • error.config:

  • 请求次数:
    可以看到控制台的 error 输出了 4 次,但是 retry 明明设置的是 3,怎么会有 4 次输出呢?这是因为 retry 设置的是最多重试几次请求,它设置的是重试次数,而第一次输出是第一次发送请求返回输出,后三次才是重试请求的输出。

二、 axios 重新发送请求升级版(能够识别出网络错误,但接口报错也会在达到请求次数后才返回)

在 if (config.__retryCount >= config.retry) {} 中增加对网络错误的识别,reject 中的内容可以自定义,这里的 reject 中写了什么,发送异步请求后的错误捕捉 catch 中的 error 就是什么。

// 如果当前发送的请求大于等于设置好的请求次数时,不再发送请求,返回最终的错误信息
if (config.__retryCount >= config.retry) {
  if (error.message === "Network Error") {
    //message为"Network Error"代表断网了
    return Promise.reject({
      type: "warning",
      msg: "网络连接已断开,请检查网络",
    });
  } else if (error.message === "timeout of 5000ms exceeded") {
    //网太慢了,5秒内没有接收到数据,这里的5000ms对应上方timeout设置的值
    return Promise.reject({ type: "warning", msg: "请求超时,请检查网络" });
  } else {
    //除以上两种以外的所有错误,包括接口报错 400 500 之类的
    return Promise.reject({ type: "error", msg: "出现错误,请稍后再试" });
  }
}
  • error.message:

三、 axios 重新发送请求高级版(非网络错误不重试请求,直接返回错误信息)

网络连接出错可以尝试多次请求,说不定哪一次网络就通了,但是如果是类似于接口的路径写错,404、500 之类的错误,其实不需要多次请求,因为再多少次的请求他们的结果也不会改变。

所以这个时候就需要拦截这样的错误,直接返回错误信息,不再重新发送请求。

可以根据 error.response.data 是否有值来判断接口有没有返回响应,data 结果为 undefined 的时候很明显就是发送了请求但是没接收到结果,可能是网络问题;data 有值也就是有返回结果, 可以根据返回结果来自定义处理内容。

在 if (!config || !config.retry) return Promise.reject(error); 的下方增加判断。

if (!config || !config.retry) return Promise.reject(error);

//如果有响应内容,就直接返回错误信息,不再发送请求
if (error.response.data) {
  return Promise.reject({ type: "error", msg: error.response.data });
}
  • 接口路径写错后的报错:(举个栗子,404 接口找不到的 error 长这样)

四、 总体代码

import axios from "axios";
//创建一个axios实例
const requests = axios.create({
  timeout: 5 * 1000, //请求超时时间(5秒后还未接收到数据,就需要再次发送请求)
  retry: 3, //设置全局重试请求次数(最多重试几次请求)
  retryDelay: 1000, //设置全局请求间隔
});

//响应拦截器
requests.interceptors.response.use(
  (res) => {
    return Promise.resolve(res.data);
  },
  (error) => {
    //console.log(error);
    //超时处理 error.config是一个对象,包含上方create中设置的三个参数
    var config = error.config;
    if (!config || !config.retry) return Promise.reject(error);

    //如果有响应内容,就直接返回错误信息,不再发送请求
    if (error.response.data) {
      return Promise.reject({ type: "error", msg: error.response.data });
    }

    // __retryCount用来记录当前是第几次发送请求
    config.__retryCount = config.__retryCount || 0;

    // 如果当前发送的请求大于等于设置好的请求次数时,不再发送请求,返回最终的错误信息
    if (config.__retryCount >= config.retry) {
      if (error.message === "Network Error") {
        //message为"Network Error"代表断网了
        return Promise.reject({
          type: "warning",
          msg: "网络连接已断开,请检查网络",
        });
      } else if (error.message === "timeout of 5000ms exceeded") {
        //网太慢了,5秒内没有接收到数据,这里的5000ms对应上方timeout设置的值
        return Promise.reject({ type: "warning", msg: "请求超时,请检查网络" });
      } else {
        //除以上两种以外的所有错误,包括接口报错 400 500 之类的
        return Promise.reject({ type: "error", msg: "出现错误,请稍后再试" });
      }
    }

    // 记录请求次数+1
    config.__retryCount += 1;

    // 设置请求间隔 在发送下一次请求之前停留一段时间,时间为上方设置好的请求间隔时间
    var backoff = new Promise(function (resolve) {
      setTimeout(function () {
        resolve();
      }, config.retryDelay || 1);
    });

    // 再次发送请求
    return backoff.then(function () {
      return requests(config);
    });
  }
);

export default requests;

标签:axios,return,请求,发送,Promise,error,超时,config
From: https://www.cnblogs.com/wp-leonard/p/17839039.html

相关文章

  • axios请求并发限制
    队列有x个之后执行正文在网上看到这么一道题:首先来实现一个分割数组的函数~constgroup=(list=[],max=0)=>{if(!list.length){returnlist;}letresults=[];for(leti=0,len=list.length;i<len;i+=max){results.push(list.s......
  • 同时调用多个异步请求
    需求为了减少页面等待时间,现有多个接口,需要同时调用。解决有两种写法:Promise.all([interfaceName1(para1),interfaceName2(para2)]).then().catch()Promise.all(arr)中的参数arr:由接口名称(接口参数)组成的数组;then((res)=>{})中的结果res:接口结果所组成的数组。例1......
  • Spring Boot 自定义注解,AOP 切面统一打印出入参请求日志
    今天主要说说如何通过自定义注解的方式,在SpringBoot中来实现AOP切面统一打印出入参日志。小伙伴们可以收藏一波。废话不多说,进入正题!一、先看看切面日志输出效果在看看实现方法之前,我们先看下切面日志输出效果咋样:从上图中可以看到,每个对于每个请求,开始与结束一目了然,并且打印......
  • java RestTemplate 发送post请求
    RestTemplate简介RestTemplate是执行HTTP请求的同步阻塞式的客户端,它在HTTP客户端库(如JDKHttpURLConnection,ApacheHttpComponents,okHttp等)基础封装了更加简单易用的模板方法API。即RestTemplate是一个封装,底层的实现还是java应用开发中常用的一些HTTP客户端。相对于直接使用底层......
  • 未预编译文件“/default.aspx”,因此不能请求该文件
    未预编译文件“/default.aspx”,因此不能请求该文件。说明:执行当前Web请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。异常详细信息:System.Web.HttpException:未预编译文件“/default.aspx”,因此不能请求该文件。 ......
  • http请求问题
    在建立http请求的时候,一定要注意请求格式:publicstaticJSONObjecthttpRequest(StringrequestUrl,StringrequestMethod,StringoutputStr){JSONObjectjsonObject=null;StringBufferbuffer=newStringBuffer();try{URLurl=newURL(requestUrl);......
  • 服务器未正确处理预检请求,解决办法
    这个错误提示表明浏览器已经阻止了跨域请求,因为服务器未正确处理预检请求。预检请求是浏览器在发送跨域请求之前,先向服务器发送一个OPTIONS请求,以确定服务器是否接受跨域请求,并确定可以使用哪些HTTP方法和请求头。为了解决这个问题,您需要在服务器端添加处理预检请求的代码。......
  • 微信小程序TypeScript请求封装(TS+request)
    目录结构-WxApp-api请求方式-index.ts统一输出api接口-base.ts环境判断-user对应数据请求-userApi.ts-utils-request.ts封装请求封装request首先,我们先搞w......
  • 微服务 在 Java 代码中发送 http 请求(跨服务远程调用)
    1.注册RestTemplate对象到Spring容器中(Bean的注入只能放在配置类里,而启动类本身就是配置类)@SpringBootApplicationpublicclassOrderServiceApplication{publicstaticvoidmain(String[]args){SpringApplication.run(OrderServiceApplication.class,......
  • cbv源码,模板,请求响应,session
    1cbv源码......