微信小程序请求队列处理token异常

前言

网络请求是开发中最基础也是最核心的需求,封装一个稳定且可用性高的请求也显得尤为重要。通常封装的内容除了入参之外,更多的是请求中的异常处理。本文分享下我在处理 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 完成,执行队列中的所有请求。

这样我们需要定义请求队列 qeueutoken 请求的标识 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 异常的做法,如果你有更好的做法或建议,欢迎交流~

以上是 微信小程序请求队列处理token异常 的全部内容, 来源链接: utcz.com/a/15353.html

回到顶部