利用 Promise 实现任务流的自动重试
时间:2022-06-06
本文章向大家介绍利用 Promise 实现任务流的自动重试,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
微信小程序不支持 HTTP 的 cookie ,其会话机制是通过开发自己维护一个 session_id 在小程序的本地存储中,每次调用 wx.request 的时候都带上这个 session_id 来实现的会话机制。
那么,有会话机制,就会存在会话失效、更新等等问题。
传统的 HTTP cookie-session 机制,当会话失效的时候,可以在 HTTP 的返回头里面通过 setcookie 来静默返回一个新的 session_id ,小程序就比较麻烦。
传统的实现方案
1.理想的实现情况
let session_id = wx.getStorageSync('session_id');
wx.request({
url: '/api/create',
header: {session_id},
method: 'POST',
data: 'hello world',
success: (resp) => {
let {id} = resp.data;
// 创建成功后,跳转去目标页面
wx.navigateTo({url: `/article?id=${id}`})
}
})
2.为了容错,我们会添加返回判断,但错误的时候,再调用一次
// 调用创建接口
function create() {
let session_id = wx.getStorageSync('session_id');
wx.request({
url: '/api/create',
header: {session_id},
method: 'POST',
data: 'hello world',
success: (resp) => {
let {status, data} = resp;
if (status === 'session_id error') {
// 与后端通信,重新下发并更新本地存储中的 session_id
// 然后再重新自行一次创建行为
updateSession().then(create);
} else {
let {id} = resp.data;
// 创建成功后,跳转去目标页面
wx.navigateTo({url: `/article?id=${id}`})
}
}
})
}
上面这种方式,在接口的返回值中做一次判断,然后再执行一次,好像就解决问题了。
但如果我们业务的接口非常多,返回判断是不是要添加很多次呢?
基于 Promise 的任务流自动重试
首先,我们先封装一个专门用来发请求的函数,并且全局套上一个会话异常的逻辑
/util/request.js
// 通用请求函数
export function request (obj) {
let session_id = wx.getStorageSync('session_id');
return new Promise((resolve, reject) => {
obj.header = {session_id};
obj.success = (resp) => {
resp.reqObj = obj;
resolve(resp);
}
obj.fail = (resp) => {
resp.reqObj = obj;
reject(resp);
}
// 发出请求
wx.request(obj);
}).then(session_error)
}
// 会话异常处理
export function session_error (resp) {
let {status} = resp.data;
// 如果 session_id 没问题,交给后续流程处理
if (static !== 'session_id error') {
return resp;
}
// 如果 session_id 有问题
return new Promise((resolve, reject) => {
// 更新 session_id
updateSession().then(() => {
// 重试之前的请求,并继续原先的流程
request(resp.reqObj).then(resolve);
});
})
}
然后,我们的业务逻辑,可以简化为
import { request } from 'util/request';
// 请求接口
request({
url: '/api/create',
data: 'hello world',
method: 'POST'
}).then((resp) => {
let {id} = resp.data;
// 创建成功后,跳转去目标页面
wx.navigateTo({url: `/article?id=${id}`})
})
不论我们业务有多少次 HTTP 请求要发送,request 函数都能自动帮我们处理好这些通用流程,且支持自动重试,自动执行原先断掉的流程。
如果是一些非全局处理的逻辑,也可以改用依赖注入的方式,交给业务代码来决定是否调用。
import { request, session_error } from 'util/request';
// 创建文章
request({
url: '/api/create',
data: 'hello world',
method: 'POST'
})
.then(session_error)
.then((resp) => {
let {id} = resp.data;
// 创建成功后,跳转去目标页面
wx.navigateTo({url: `/article?id=${id}`})
})
// 拉取公告,不需要会话态
request({
url: '/api/public_msg',
method: 'GET'
})
.then((resp) => {
let msg = resp.data;
msg && wx.showModal({title: '公告', content: msg});
})
结语
这种基于 Promise 的任务流自动重试,在 Web 应用里面有非常多的使用场景,这里仅仅以小程序的会话态举例。
演示代码为了突出重点,省略了 reject 和重试次数的处理部分,大家记得加上,要不然会出现外层的 catch 不到错误又或者是一直在循环重试。
- mongodb取出json,利用python转成dataframe(dict-to-dataframe)
- JSP简单入门(2)
- JSP简单入门(3)
- 物化视图相关的性能改进 (r7笔记第58天)
- Maven 核心原理解析(1)
- LeetCode——Two Sum
- TensorFlow全新的数据读取方式:Dataset API入门教程
- 不经意发现的dba_objects和dba_tables中的细节(r7笔记第56天)
- LeetCode——Longest Substring Without Repeating Characters
- Python time模块详解(时间戳↔元组形式↔格式化形式三者转化)
- Maven 核心原理解析(2)
- Linux C 编程——互斥锁mutex
- python两个 list 获取交集,并集,差集的方法.
- python——时间与时间戳之间的转换
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- SAP Cloud for Customer Oberon视图里的Ruby Scrip
- 干了SAP开发这么多年,我都积累了哪些程序调试技巧
- 谈谈SOCKET
- 使用ABAP实现Mock测试工具Mockito
- 增强版本的自开发SAP WebClient UI Repository Information System
- 最大子序列和的问题的解(1)
- 10-STM32+ESP8266+AIR202远程升级方案-功能3-手机APP控制STM32远程更新固件程序,基于ESP8266
- 最大子序列和的接口函数(2)
- 最大子序列和的接口函数(3)
- 【剑指Offer】二叉树的深度
- 运行时间中的对数
- IIC协议
- 通过例子学习编写shell
- 【redis6.0.6】redis源码慢慢学,慢慢看 -- 第三天:MakeFile
- 继续学习Shell脚本(详细)