维护你的请求队列,处理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 完成,执行队列中的所有请求。
这样我们需要定义请求队列 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 异常的做法,如果你有更好的做法或建议,欢迎交流~
维护你的请求队列,处理token异常的更多相关文章
- Android-Volley网络通信框架(二次封装数据请求和图片请求(包含处理请求队列和图片缓存))
1.回想 上篇 使用 Volley 的 JsonObjectRequest 和 ImageLoader 写了 电影列表的样例 2.重点 (1)封装Volley 内部 请求 类(请求队列,数据请求,图片 ...
- 编写简单的ramdisk(有请求队列)
前言 前面用无请求队列实现的ramdisk的驱动程序虽然申请了请求队列,但实际上没用上,因为ramdisk不像实际的磁盘访问速度慢需要缓存,ramdisk之间使用内存空间,所以就没用请求队列了.本文将 ...
- 编写简单的ramdisk(无请求队列)
最近在研究块设备驱动的编写,看了赵磊大牛的<写一个块设备驱动>,受益匪浅,虽然能看懂里面说的,但动手写写代码还是能加深理解的,下面实现的ramdisk写的很简单,如果有错误,欢迎大牛们指正 ...
- ASP.Net的工作线程与请求队列
当 ASP.NET 接收针对页的请求时,它从线程池中提取一个线程并将请求分配给该线程. 一个普通的(或同步的)页在该请求期间保留线程,从而防止该线程用于处理其他请求.如果一个同步请求成为 I/O bo ...
- mvc 使用预置队列类型存储异常对象
using PaiXie.Utils; using System; using System.Collections.Generic; using System.Linq; using System. ...
- springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。
springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑. 1.1 异常处理思路 系统中异常包括两类:预期异常和运行时异常RuntimeEx ...
- 统一处理jquery ajax请求过程中的异常错误信息的机制
当jQuery ajax向服务器发送请求,服务器发生异常,比如:400.403.404.500等异常,服务器将异常响应给客户端,此时的ajax可以获取异常信息并进行处理,但此时我们一般是跳转到与异常编 ...
- axios中为所有请求带上Token头
axios中为所有请求带上Token头 https://www.imooc.com/article/27751
- golang API 请求队列
概要 实现思路 使用方法 启动队列服务 使用队列服务 概要 在调用第三方 API 的时候, 基本都有访问限速的限制条件. 第三方的 API 有多个的时候, 就不太好控制访问速度, 常常会导致 HTTP ...
随机推荐
- 《SDN期末作业——实现负载均衡》
队名:取个队名真难 一.网络拓扑(场景二) 二.负载均衡程序 1.建立拓扑的代码 拓扑 2.下发组表流表的代码 下发组表流表 三.演示视频 1.目的 服务器h2,h3,h4上各自有不同的服务,h1是客 ...
- 利用ajax 引入静态页公共的头部与底部
利用ajax引入公共的头部与底部或者多个页面需要用到的重复的组件,对于新入门的前端来说是很实用的方法,自己也是新手菜鸟一枚,折腾了好久,实现的方法有很多种,这是我个人觉得比较简单方便的 首先得把公用的 ...
- HTTP GET请求302重定向问题
1.问题描述 ① 在华为云服务器中搭建了java环境,并在tomcat中部署了一个空的web项目 ② 在此web项目中上传了一个名为:plugin_DTDREAM_LIVING_DEHUMIDIFIE ...
- Linux基本操作及常用指令
今天复习了下Linux的基本操作及常用指令,上学期大数据云计算课一直也在用linux系统还是比较熟悉的,并在centos6.7虚拟机上部署了前几天做的web项目,了解了Nginx的反向代理与负载均衡, ...
- FPGA边沿检测Verilog代码
FPGA边沿检测Verilog代码(上升沿,下降沿,双边沿) 实现思路:用两个一位寄存器直接异或可以实现 代码实现: module edge_detect( input clk, input rs ...
- SpringBoot框架——从SpringBoot看IoC容器初始化流程之方法分析
目录 一.概观Spring Boot 二.Spring Boot应用初始化 2.1 初始化入口 2.2 SpringApplication的run方法 2.3 方法分析 三.容器创建与初始化 3.1 ...
- CSS 权重图
关系图 图片出处我找不到了. 结论 权重从高到低排序 1. !important 2. style 3. #id 4. .class .child-class 5. .class1.class2 6. ...
- 《深入理解 Java 虚拟机》读书笔记:虚拟机字节码执行引擎
正文 执行引擎是 Java 虚拟机最核心的组成部分之一.在不同的虚拟机实现里,执行引擎在执行 Java 代码时可能会有解释执行(通过解释器执行)和编译执行(通过即时编译器产生本地代码执行)两种选择,也 ...
- django中CBV源码分析
前言:Django的视图处理方式有两种: FBV(function base views) 是在视图里基于函数形式处理请求. CBV(class base views)是在视图里基于类的形式处理请求. ...
- Jmeter——如何使得token在各线程组间引用的游刃有余
在以前的博文中,有介绍过,jmeter基本的关联,关联就是将参数在各接口中动态传参,使得接口脚本变得灵活使用,非一次性脚本.今天再来介绍一种jmeter全局变量的设置与使用,可以让脚本运用更丰富,场景 ...