拦截器
实例化请求
import Request from './request'
const wxRequest = new Request()
请求拦截
添加token
wxRequest.interceptors.request.use(config => {
config.header['ACCESS_TOKEN'] = wx.getStorageSync('token');
return config
})
响应拦截
刷新token
let tokenRequestPromise = null; // [刷新请求]的状态
let isRefreshing = false; // 是否在处理[刷新请求]
function createTokenRequest() {
// ... 模拟刷新请求token
}
async function refreshToken() {
if(!isRefreshing) {
isRefreshing = true
// tokenRequestPromise被直接赋值为request返回的Promise,与finally无关。 finally为promise的最终回调
tokenRequestPromise = createTokenRequest().finally(() => {
isRefreshing = false
})
}
return tokenRequestPromise
}
wxRequest.interceptors.response.use(async (response) => {
if (response?.data?.code === 2001) { // 假设为token过期/失效
await refreshToken() // 等待刷新完成,所有请求均等待同一个请求的Promise,不会重复
const config = response.config
return wxRequest.request(config) // 重新请求返回新的Promise(Promise链式反应,所以可以直接往外抛)
}
return Promise.resolve(response); // 非token失效,正常返回
});
错误重试
wxRequest.interceptors.response.use(async (response) => {
if (response?.data?.success === false) {
const config = response.config
if (!config || !config.retry) { // 检查配置
return Promise.reject(response.data);
}
config.__retryCount = config.__retryCount || 0; // 初始化重试计数
if (config.__retryCount >= config.retry) { // 判断是否超过重试次数
return Promise.reject(response.data);
}
config.__retryCount += 1; // 增加重试计数
const backoff = new Promise(resolve => { // 延时处理
setTimeout(resolve, config.retryDelay || 1000);
});
await backoff; // 等待延迟后重新发起请求
return wxRequest.request(config); // 重新发起请求
}
return response; // 返回处理后的响应
});