🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 前言 在我们的业务请求中,有很多时候会针对有不同时长的需求策略性设置。这里针对这个需求进行详细的展开。 针对这种情况,我们的timout的一般是根据请求地址来的,所以核心处理技巧便是如何根据不同的request地址去设置不同的timeout. 我们之前设置的请求时长是十秒,并且是通过create的部分,整个项目只有一个instance的。 ``` let _axios = axios.create({ baseURL: apiProxyUrl, headers: { 'Content-Type': 'application/json' }, transformRequest: [transformRequest], timeout: 10000 }) ``` 那么既然需要处理request的地址部分,我建议针对长时长的地址单独一个文件维护,考虑到了以下两点: ``` 1 请求地址变多时,可以更好的定位以及维护 2 需要时,可以针对不同的微服务进行进一步的管理和配置 3 与下面请求时长的策略部分进行解耦 ``` 主要结果是返回一个期望长时长地址的数组。 ``` /** * @author robin * @description maintain all long time api request paths */ /** * 用户服务长时长地址数组 */ const userApiPaths = [] /** * 报表服务长时长地址数组,如果你的微服务地址符合一个规律,可以这里进行方法定义并返回 */ const getTablesApiPaths = ()=>{ return [] } export default [ '/house/list/houseSpaceInHouseSpaceManager' ].concat(userApiPaths).concat(getTablesApiPaths()) ``` ## 简单处理 我们知道axios本身的request支持拦截器的配置,那么我们可以进行以下简单的设置。 ``` import longTimeApiEnum from './longTimeApiEnum' // 请求拦截器 _axios.interceptors.request.use((config) => { // 请求时长10分钟 const LONG_TIMEOUT = 600000 if (longTimeApiEnum.some(url => config.url.includes(url))) { config.timeout = LONG_TIMEOUT } return config }) ``` 此方法适用于大部分请求地址没有规律性,适合用枚举维护相应地址的。 ## 策略模式处理 当然如果你的长时长的api地址具有一定的正则可匹配性,也可以用正则来写,并且把判断的部分用策略模式独立为一个方法,甚至一个文件。 比如下面的例子: ``` // 根据微服务一级地址判断 function judgeIsLongTimeApi(url){ const strategy = { 'user':function(url){ if(url.includes('/users/data')) return true; return false }, 'table':function(url){ if(url.includes('/table')) return true; return false } } const firstPath = url.split('/')[1]; return strategy[firstPath] && strategy[firstPath](firstPath); } // 使用 const LONG_TIMEOUT = 600000 if (judgeIsLongTimeApi(config.url)) { config.timeout = LONG_TIMEOUT } ``` ## 复杂的类处理 感觉上面的方式不够逼格,或者有时候不是这么简单的改一个timeout,还需要改很多配置,比如说baseUrl等等。那么你需要定义一个class。然后根据你的需求去自定义每个子类。大概是这样的:这里用到了class继承。 ``` import axios from 'axios'; class Api{ constructor(){ } nessaryFn(){ throw Error('必须要实现的函数') } } class usualApi extends Api { constructor(){ } nessaryFn(){ //codes here } } class specialApi extends Api { constructor(){ } nessaryFn(){ //codes here } } // 再来一个策略模式 根据不同的情况 ,返回使用不同的api实现子类。 ``` ## 小结 以上就是全部的关于axios部分的自定义维护时做的思考和实践,已经完整的解决了自己的需求。 ## 其他问题 - 当axios的请求返回类型为非json类型,需要针对url进行特殊化配置的时候,相应的思路也是如此。 ``` if (exportXlsEnum.some(url => config.url.includes(url))) { config.responseType = 'blob' } ```