内容简介:网络请求是开发中最基础也是最核心的需求,封装一个稳定且可用性高的请求也显得尤为重要。通常封装的内容除了入参之外,更多的是请求中的异常处理。本文分享下我在处理下面以封装微信小程序请求作为例子,这是一个基础的公共请求:
前言
网络请求是开发中最基础也是最核心的需求,封装一个稳定且可用性高的请求也显得尤为重要。通常封装的内容除了入参之外,更多的是请求中的异常处理。本文分享下我在处理 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 异常的做法,如果你有更好的做法或建议,欢迎交流~
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- rabbitmq实现延时队列(死信队列)
- 消息队列(三)常见消息队列介绍
- 消息队列探秘 – RabbitMQ 消息队列介绍
- 消息队列和任务队列有什么区别?
- 数据结构之——队列与循环队列
- Redis应用-异步消息队列与延时队列
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。