这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」。
功能设计
axios是目前非常流行的http请求库,但是不管是B端,还是C端的新项目。我们都有一个很大的问题就是每次用起来就要去百度,google,bying搜索如何从0还是配置,于是我们就想二次封装axios,省去很多繁杂的业务流程,我梳理了如下业务痛点,根据目前的痛点做了一部分梳理
- 重复请求缓存(两种情况)
- 错误异常是否 抛出 或者 return
- 全局异常捕捉控制
- 超时时间设置,请求超时的重发
- 支持取消请求 (这里要兼顾多种场景)
- 考虑JSONP
- 支持自定义拦截器
- 全局配置
- debug模式(耗时)
- 自定义answer通用对象
- 提供自定义代理(mock server)
- 多种环境考虑设计
使用方式
1. `import {create} from 'http';`
1. ``
1. `const http = create({`
1. `baseUrl:'http://baidu.com/'`
1. ``
1. `Headers:{`
1. `'ua':'ios',`
1. `}`
1. ``
1. `isProd:true,//是否所有切为正式接口`
1. ``
1. `timeout:5000,`
1. ``
1. `answer:true, // 是否启用 answer对象`
1. ``
1. `JSONP:false,//JSONP模式开启`
1. ``
1. `isTimeoutRefresh,//是否重发`
1. ``
1. `debug:true, // 调式是否开启`
1. ``
1. `// 如何判断响应为成功`
1. `answerInterceptor:(answer){`
1. `// 根据后端业务状态码表`
1. `if(answer.get('code') == 200000){`
1. `answer.setOk(true);`
1. `}`
1. `return answer;`
1. `}`
1. ``
1. `});`
1. ``
1. `const an = await http.get('column/column-info/v2.0',{columnId:26219422});`
全局环境切换
提供全局的环境切换,我们预配置环境config,通过预配置的环境进行逻辑开发,提供一个switch的切换方法,方便全测,正式,mock等环境进行切换。不需要每次手动更改baseURL的逻辑
1. `// 需要预先配置 config`
1. `local:{`
1. `proxy:'localhost://testapi'`
1. `},`
1. ``
1. `dev:{`
1. `proxy:'http://123.12.3.0'`
1. `}`
1. ``
1. `prod:{`
1. `proxy:'http://baidu.com`
1. `}`
1. ``
1. `http.switchToEnv('envB'); //切换环境为 evnB`
统一的事件处理系统
使用完整的事件系统的好处是什么呢,首选我们能够监听一个完整的http请求和响应的过程,在此过程中我们做了事件机制,在request,response,error三个事件中可以更加清楚的处理个各自的逻辑,直接将解耦了内容,我们不需要再去axios的请求拦截器,响应拦截器去处理逻辑,首先是晦涩难懂,二是逻辑严重耦合。采用事件机制我们的功能模块处理更好的抽离出来。
# 事件系统
- 开始请求
```
http.on('request',request=>{ request.url = 'https:' +request.url ; return request})
```
- 响应
```
http.on('response',response=>{ return response;})
```
- 统一全局错误捕获
```
http.on('error',err=>{ // 错误处理 console.log(err)})
```
通用应答对象
为什么要做通用应答对象,这是业务中痛点最明显的,可以发现我们状态码很多都是一个固定的成功码,失败码,然后我们要判断成功,判断失败进行重复的逻辑判断,这时候既然是二次封装,那我们就将它抽离出来,然后抽离出来进行生成一个统一的应答对象。这个对象只需要判断isOk即可,完全不需要判断内部状态时变动还是迁移,解决了前后端联调的问题。
1. `const an = await miguHttp.get('column/column-info/v2.0',{columnId:26219422});`
1. `// 成功`
1. `if(an.ok){`
1. `answer.get('code')`
1. `}`