

维护你的请求队列,处理token异常
source link: http://www.cnblogs.com/chanwahfung/p/12631254.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言
网络请求是开发中最基础也是最核心的需求,封装一个稳定且可用性高的请求也显得尤为重要。通常封装的内容除了入参之外,更多的是请求中的异常处理。本文分享下我在处理 token
异常方面的做法,通过维护请求队列,实现重发请求,减少 token
重复请求。
公共请求方法
下面以封装微信小程序请求作为例子,这是一个基础的公共请求:
common({ baseUrl = this.baseUrl, method, url, data, header }) { return new Promise((resolve, reject) => { let token = wx.$utils.getStorageToken() wx.request({ method, url: baseUrl + url, data, header: { 'Content-Type': 'application/x-www-form-urlencoded', token, ...header }, success: (res) => { if (res.data.code == 0 || res.data.code == 500) { // 失败 reject(res.data) } if (res.data.code == 1) { // 成功 resolve(res.data) } if (res.data.code == -1) { // token过期 // token过期处理 } }, fail: reject }) }) }
token过期重发请求
getToken
方法内部会将 token
存储到本地中
success: (res) => { res = res.data if (res.code == 0) { reject(res.msg) } if (res.code == 1) { wx.setStorageSync('loginInfo', res.data) resolve(res.data.token) } }
当 token
过期,在等待 getToken
后,再次发送请求,将结果 resolve
common({ baseUrl = this.baseUrl, method, url, data, header }) { return new Promise((resolve, reject) => { let token = wx.$utils.getStorageToken() wx.request({ method, url: baseUrl + url, data, header: { 'Content-Type': 'application/x-www-form-urlencoded', token, ...header }, success: async (res) => { if (res.data.code == 0 || res.data.code == 500) { reject(res.data) } if (res.data.code == 1) { resolve(res.data) } if (res.data.code == -1) { + await this.getToken() + this.common({ baseUrl, method, url, data, header }) + .then(resolve) + .catch(reject) } }, fail: reject }) }) }
这样看起来好像没什么问题,但由于内部没有限制处理,有 n 个请求就会发起 n 个 getToken
请求。这当然不是我们想要的,就像下面这样重复发起了两次 wxLogin
:
维护请求队列
理想的情况是: token
过期后,发起一个 getToken
请求。每当有请求进来,将它存入队列中,等待 getToken
完成,执行队列中的所有请求。
这样我们需要定义请求队列 qeueu
和 token
请求的标识 isTokening
,还有加入队列方法 pushQeueu
和执行队列方法 execQeueu
。
{ qeueu: [], isTokening: false, pushQeueu({ method, url, data, header, resolve, reject }){ this.qeueu.push({ data: { method, url, data, header }, resolve, reject, request: (data)=> this.common(data) }) }, execQeueu(){ this.qeueu.forEach((item, index) => { item.request(item.data) .then(item.resolve) .catch(item.reject) // 执行完任务后 清空队列 if(index === this.qeueu.length-1){ this.qeueu.length = 0 } }) } }
处理如下:
common({ baseUrl = this.baseUrl, method, url, data, header }) { return new Promise((resolve, reject) => { let token = wx.$utils.getStorageToken() wx.request({ method, url: baseUrl + url, data, header: { 'Content-Type': 'application/x-www-form-urlencoded', token, ...header }, success: async (res) => { if (res.data.code == 0 || res.data.code == 500) { reject(res.data) } if (res.data.code == 1) { resolve(res.data) } if (res.data.code == -1) { + this.pushQeueu({ method, url, data, header, resolve, reject }) + if(this.isTokening === false){ + this.isTokening = true + await this.getToken() + this.isTokening = false + this.execQeueu() + } } }, fail: reject }) }) }
发起 getToken
请求后,将 isTokening
置为 true
表示正在请求中。当再有请求进入时,则不会再重复发送 getToken
。
处理getToken错误
getToken
在发生错误时,我们应当捕获错误,不继续执行请求队列并清空队列
if (res.data.code == -1) { this.pushQeueu({ method, url, data, header, resolve }) if(this.isTokening === false){ this.isTokening = true let err = await this.getToken().then(res => null).catch(err => err) if(err){ this.qeueu.length = 0 console.error(err) }else{ this.isTokening = false this.execQeueu() } } }
写在最后
以上是我在处理 token 异常的做法,如果你有更好的做法或建议,欢迎交流~
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK