广州最好的网站建设公司,巴中公司网站建设,啥也不懂怎么建设网站,wordpress检查全站链接路漫漫其修远兮#xff0c;前端道路逐渐迷茫#xff0c;时隔好久好久终于想起了我还有一个小博客#xff0c;最近在一直在弄uniapp#xff0c;属实有被恶心到#xff0c;但也至少会用了#xff0c;最近实现了一个比较通用的功能#xff0c;就是无感刷新token#xff0c…路漫漫其修远兮前端道路逐渐迷茫时隔好久好久终于想起了我还有一个小博客最近在一直在弄uniapp属实有被恶心到但也至少会用了最近实现了一个比较通用的功能就是无感刷新token但在过程中发现一个问题就是token刷新了接口也重新请求了但页面数据就是没有刷新。
上面问题归根结底还是自己对于promise、async、await等知识理解不够深刻导致的先看看无感刷新token怎么实现的吧废话不多说上代码代码都有注释
import Request from ./request // 对uniapp.request的简易封装
import { getRefreshToken } from /common/api/apis.js // 刷新token接口
const http new Request()let isRefresh false // 是否处于刷新token状态中
let fetchApis [] // 失效后同时发送请求的容器
let refreshCount 0 // 限制无感刷新的最大次数
function onFetch(newToken) {refreshCount 1if (refreshCount 3) {refreshCount 0fetchApis []return Promise.reject()}fetchApis.forEach(callback {callback(newToken)})// 清空缓存接口fetchApis []return Promise.resolve()
}// 响应拦截(主要看error,因为token过期一般你们后端接口都是返回401/402在对应case下处理刷新token逻辑即可)
http.interceptor.response((response) {/* 请求之后拦截器 */if (response.config.loading) {uni.hideLoading()}// 请求成功但接口返回的错误处理if (response.data.statusCode response.data.statusCode ! 200) {if (!response.config.needPromise) {console.log(error, response)uni.showModal({title: 提示,content: response.data.message,showCancel: false,confirmText: 知道了})// 中断return new Promise(() {})} else {// reject Promisereturn Promise.reject(response.data)}}return response
}, (error) {// 请求错误做点什么const token uni.getStorageSync(token)const refreshToken uni.getStorageSync(refreshToken)// DESC: 不需要做无感刷新的白名单接口const whiteFetchApi [/dealersystem/jwtLogin, /dealersystem/smsLogin, /sso2/login, /dealersystem/isLogin]switch (error.statusCode) {// token过期处理实现无感刷新case 401:case 402:// 如果登录过token过期走refreshToken逻辑if (token !whiteFetchApi.includes(error.config.url)) {if (!isRefreshing) {isRefreshing truegetRefreshToken({ refreshToken }).then(res {let newToken res.dataonTokenFetched(newToken).then(res {}).catch(err {// 超过循环次数时回到登录页这里可以添加你执行退出登录的逻辑uni.showToast({ title: 登录失效请重新登录, icon: error })setTimeout(() {uni.reLaunch({url: /pages/login/login})}, 1500)})}).catch(err {// refreshToken接口报错证明refreshToken也过期了那没办法啦重新登录呗uni.showToast({ title: 登录失效请重新登录, icon: error })setTimeout(() {uni.reLaunch({ url: /pages/login/login })}, 1500)}).finally(() { isRefreshing false })}return new Promise((resolve) { // 此处的promise很关键就是确保你的接口返回值在此处resolve以便addFetchApi((newToken) {error.config.header.token newTokenresolve(http.request(error.config))})})} else {// 没有登录过直接输入链接访问的情况if (whiteFetchApi.includes(error.config.url)) {return Promise.reject(error.data)}uni.showToast({ title: 您未登录请前往登录, icon: error })setTimeout(() {uni.reLaunch({ url: /pages/login/login })}, 1500)return Promise.reject(error.data)}default:errorMsg error.data.message || break}uni.showModal({title: 提示,content: errorMsg,showCancel: false,confirmText: 知道了})return Promise.reject(error.data)})业务侧列表页请求接口我的问题就在于调用接口后下方的代码不执行导致页面数据不更新 也就是说该语句没有resolve回结果
那么怎么排查问题呢首先先复现问题 1、token我在localStorage缓存了一份可以在谷歌浏览器中更改token模拟token过期 2、触发如上项目列表的分页接口 可以看到已经触发了刷新token接口并且重新请求上次失败的列表接口无感刷新token逻辑已经正常但为什么列表接口请求成功还一直loading没关闭捏就是因为后续代码未执行await接口的返回没有成功resolve
3、排查await的列表接口为何没有成功resolve (1) 列表页 (2) 接口配置页 (3) 接口全局配置文件api/index.js就是在此处将接口返回数据resolve回来此时再看http.request方法 (4) uni.request封装文件request.js发现问题所在当接口请求失败时这里直接reject了那么真相大白
熟悉promise的话应该知道
resolve一个promise相当于返回一个新的promiseawait语句要成功获取到值时该promise必须是resolve的fulfilled状态如若未对await语句进行try catch处理那么会阻止后续代码的执行 所以怎么改呢将上述request.js文件的reject替换成resolve即可解决啦