<p> 需求</p>
- 封装常用请求
- 拦截器-请求锁
- 统一处理错误码
<p> </p>
<p>一、封装常用的请求</p>
<p> 解决痛点:不要每一个模块的api都还要写get,post,patch请求方法。直接将这些常用的方法封装好。</p>
<p> 解决方案:写一个类,封装好常用的请求</p>
<p> 部分源码如下</p>
export default<span> class PublicAPI { constructor(url) { this.url =<span> url; } get(params, filter) { if<span> (Array.isArray(params)) { filter = typeof filter === 'object' ?<span> JSON.stringify(filter) : filter; let qs = filter ? '?filter=' + filter : ''<span>; return axios.get(this.url + '/' + params.join('/') +<span> qs); } params = params ||<span> {}; return axios.get(this<span>.url, { params }); } delete<span>(id) { return axios.delete(${this.url}/${id}
); <span> } post(params) { return axios.post(this<span>.url, params); }
//常用请求 都可以封装在这里 }</span></span></span></span></span></span></span></span></span></span></span>
<p> </p>
<p>二、拦截器-请求锁</p>
<p> 解决痛点:限制同一时间发多个同一个请求</p>
<p> 解决方案:利用axios的拦截器 + axios.CancelToken,限制同一个请求多次发送</p>
<p> 源码如下</p>
<p>方案一:简单款</p>
let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识 let CancelToken =<span> axios.CancelToken; let removePending = (config) =><span> { for(let p in<span> pending){ if(pending[p].u === config.url + '&' + config.method) { //当前请求在数组中存在时执行函数体 pending[p].f(); //执行取消操作 pending.splice(p, 1); //把这条记录从数组中移除 <span> } } }</span></span></span></span>
<p>方案二:复杂款(这个是在掘金上看到的,原链接找不到了)</p>
let pending =<span> {}; /** * cancelKey管理器 * * @return {Object} 返回一个对象,对象暴露两个方法,一个可以获取本次请求的key,一个是设置本次请求的key * @memberof HttpRequest /<span> let cancelKeyManager = () =><span> { const expose =<span> {}; expose.setKey = function<span> setKey(config) { const { method, url, params, data } =<span> config; expose.key =${method}|<span>${url}
; //expose.key = method === 'get' ?${expose.key}&${JSON.stringify(params)}
:${expose.key}&${JSON.stringify(data||{})}
; <span> }; expose.getKey = function<span> getKey() { return<span> expose.key; }; return<span> expose; }; / 处理请求拦截和请求取消 @param {object} config axios配置对象 @param {boolean} [isCancel=true] 标识是请求取消还是拦截请求 @return {object} 返回axios配置对象 @memberof HttpRequest /<span> let handleRequestCancel = (config, isCancel = false) =><span> { // 设置本次请求的key const { setKey, getKey } =<span> cancelKeyManager(); setKey(config); const key =<span> getKey(); const CancelToken =<span> axios.CancelToken; // 取消已经发出去的请求 if<span> (isCancel) { removeRequest(key, true<span>); // 设置本次请求的cancelToken config.cancelToken = new CancelToken(c =><span> { pending[key] =<span> c; }); } else<span> { // 拦截本次请求 config.cancelToken = new CancelToken(c =><span> { // 将本次的cancel函数传进去 pending[key] =<span> c; removeRequest(key, true<span>, c); }); } return<span> config; }; / 移除请求 @param {string} key 标识请求的key @param {boolean} [isRequest=false] 标识当前函数在请求拦截器调用还是响应拦截器调用 @param {function} c cancel函数 @memberof HttpRequest */<span> let removeRequest = (key, isRequest = false, c) =><span>{ // 请求前先判断当前请求是否在pending中,如果存在有两种情况: // 1. 上次请求还未响应,本次的请求被判为重复请求,则调用cancel方法拦截本次重复请求或者取消上一个请求 // 2. 上次请求已经响应,在response中被调用,清除key <span> console.log(key,pending); if<span> (pending[key]) { if<span> (isRequest) { Message.error({ message: '请求过于频繁'<span> }); } else<span> { // 上一次请求在成功响应后调用cancel函数删除key delete<span> pending[key]; } } };</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
<p> </p>
<p>三、统一处理错误码</p>
<p> 解决痛点:每个请求都需要处理错误信息,特别是一些常用的错误(坚持能封装就封装的思想),当然具体业务处理逻辑这是各自处理啦!</p>
<p> 解决方案:用axios拦截器,将返回来的错误统一处理,最常用的就是401 token失效吧!一般是要前后端统一错误码的,固定的错误码做固定的事情!</p>
<p> 部分源码如下(感觉只适合部分)</p>
axios.interceptors.response.use(
response => {
return new Promise((resolve, reject) => { //很重要 用promise 接收自定义错误码
let data = response.data;
if (data.code === 'ok') {
return resolve({
data: data.data || data || {},
response: response
});
} else {
switch (data.code) {
case '10500': //自定义code
reject({
response: {
code: '10500',
status: 500,
msg: data.msg
}
});
break;
default:
reject(response);
}
}
});
},error => {}
)<p> </p> <p>总结</p> <p> 给出的源码比较分散,仅提供思路。</p> <p> 在项目中这么一套全家桶用下来,十分巴适~~~</p> <p> 有疑问可以给我留言,我会尽力解答哦</p>
向你申请交换首页友情链接,同意的话请回复一下
生活常识网
http://wozhidaole.com.cn/
网友们想与我站互相友情链接的,可以去我站申请!
已添加贵站友链