普通人的星光灿烂,大多数人的生存模板,加油
最近群友提出一个需要,用户在首页的时候调用接口,
- 接口申请有上线,超出的局部在已实现之后持续申请;
- 接口 token 生效了,或者是无权限,如何在第一次发现接口 401 的状况下,勾销剩下的接口申请,并且重定向到 401,
其中的难点次要是在如何勾销申请,我查阅了 uni.request 的文章,它提供了跟原始 XHR 一样的停止申请的办法 abort();
解决方案 (思路)
- 设置最大申请数 limit, 当申请数量超出的局部, 将申请放在一个数组队列外面 waitingList, 期待, 当后面的申请实现的时候,每次都去取出 waitingList 第 0 个元素, 如果有申请,那么就执行,如果没有,就 return
- 正在执行的申请都会存入 excutingList 执行队列当中, 当发现接口的返回 code == 401 时, 将剩下的接口都执行 abort() 办法,即中断接口申请, 而后在将以后页面的地址重定向到 login 页面
流程图如下:
如果可能真正了解流程图的话,我想实现理论是简略的, 能够本人手动尝试封装, 如果有不懂的局部能够查看以下的代码:
import Config from '@/common/config.js';
const waitingList = []; // 期待申请队列
const excutingList = []; // 执行队列
const limit = 10; // 最大申请数
const excuteWaitingList = () => {const func = waitingList[0];
if (typeof func === 'function') {func();
}
waitingList.splice(0, 1);
};
const requestPromise = (
resolve,
reject,
url,
method = 'get',
params,
callback
) => {const token = Config.token || uni.getStorageSync('token');
let headers = {};
if (token) {headers['Authorization'] = 'Bearer' + token; // 让每个申请携带自定义 token 请依据理论状况自行批改
}
let success = false;
const baseUrl = Config.baseUrl + Config.requestPrefix;
const requestTask = uni.request({url: url.startsWith('https://') ? url : baseUrl + url, // 仅为示例,并非实在接口地址。method: method ? method.toUpperCase() : '',
header: headers,
data: params,
success: (res) => {
const result = res;
if (url.startsWith('https://')) {resolve(result.data);
}
let errorMsg = '申请有误';
if (result && result.data) {if (result.data.code === 200) {
success = true;
resolve(result.data);
} else if (result.data.code === 401) {if (window.location.href.includes('/pages/dashboard-login/index')) {
uni.reLaunch({url: '/pages/dashboard-login/index',});
Config.clearAllRequest();} else
if (uni.commonData.currentPage !== 'login') {
uni.reLaunch({url: '/pages/login/index',});
Config.clearAllRequest();}
reject(errorMsg);
} else {
errorMsg = result.data.msg || errorMsg;
reject(errorMsg);
// reject(result.data)
}
} else {reject(errorMsg);
}
},
fail (res) {console.error(res, 'fail')
reject('服务异样');
},
complete () {if (success) {resolve(true);
} else {resolve(false);
}
let index = excutingList.indexOf(requestTask);
excutingList.splice(index, 1);
if (typeof callback === 'function') {callback();
}
// console.log('complete')
// console.log(tasks, 'tasks')
// console.log(waitingList, 'waitingList')
// console.log(excutingList, 'excutingList')
excuteWaitingList();},
});
excutingList.push(requestTask);
};
export default function ajaxRequest (url, method = 'get', params) {const promiseObj = new Promise((resolve, reject) => {if (excutingList.length > limit) {waitingList.push((callBack) => {requestPromise(resolve, reject, url, method, params, callBack);
});
} else {requestPromise(resolve, reject, url, method, params);
}
});
return promiseObj;
}
Config.clearAllRequest = () => {excutingList.map((item) => {if (item && item.abort) {item.abort();
}
});
waitingList.length = 0;
excutingList.length = 0;
}
课后作业
思考下如果应用 Axios 要如何实现以上的需要,欢送小伙伴在评论区评论以及说下本人的思路, 哈哈
写在最初
我是 crazyu,一位前端开发工程师。
- 文中如有谬误,欢送在评论区斧正,如果这篇文章帮到了你,欢送点赞和关注😊
- 本文首发于微信公众号:crazyu 前端,未经许可禁止转载
本文由 mdnice 多平台公布