背景:项目中用到第三方接口,第三方认证机制要求数据请求中带上token认证。token有效时间是30分钟,refreshtoken有效时间30天。token过期,需要用refreshtoken重新获取。面临问题:如果token已失效,此时页面发送多个数据请求,为保证token有效,可能需要重复发送多个冗余token请求。
前两天有人写过获取方案,但是是基于axios实现的,我们的项目使用的是原生fetch、promise,不可能为了这个适配再专门引入axios,故自己抽时间实现了一个原生版的。
主要思想就是封装请求接口,每一个数据请求发起之前先检测token是否不存在或已过期。token无效时,发起token获取请求,这期间的数据请求都先缓存在promise中。待到token刷新后,再一一处理。
var isLoading = false;
var isTokenInvalid = false;
var promise = null;
// 暴露给外部的接口
function post(api) {
// 正在加载token, 且还没有生成promise
if (isLoading === true) {
return promise.then(() => {
// 此处一定要return promise
return request(api)
})
} else if (!isTokenInvalid) {
// 还没有生成token
promise = new Promise((resolve, reject) => {
isLoading = true;
// 模拟token获取函数
setTimeout(() => {
token = 12;
console.log('生成token')
isTokenInvalid = true;
isLoading = false;
resolve();
}, 2000);
});
return promise.then(() => {
return request(api)
});
} else {
return request(api);
}
}
// 内部函数
function request(api) {
return new Promise((resolve) => {
// 模拟数据请求接口
setTimeout(() => {
console.log('result:' + api + ' ' + new Date().toLocaleString())
resolve(api + '请求结果');
}, 5000)
});
}
// 测试函数
function test() {
Promise.all([post('api1'), post('api2')]).then((res) => {
console.log(res)
})
}
test();