微信小程序的 request 处理方式,及微信小程序 request 的错误处理
程序员文章站
2022-06-16 11:20:00
...
微信小程序是一种借助互联网获取内容的应用,而非单机应用,对互联网通信的依赖很深。因此,微信小程序在开发过程中最重要的一环就是处理前后台通信。
在基本应用中,常常会遇到,请求失败,或者操作数错误的情况;请求失败多数情况下是前后台通信不畅造成的,例如,不稳定的蜂窝数据环境下或者较为拥堵的宽带网络下,通常,一个前端 request 方法应该具备会处理这些问题能力。
- 不稳定网络环境造成的通信失败 - 再次请求,通常会进行 3 次请求
- 不稳定网络环境,造成网络通信迟缓 - 超过 3 秒钟后台没有返回数据,则弹出等待请求提示(通常为loading)直到返回结果或者服务器超时为止
- 不稳定环境造成通信超时 - 再次请求一次,如果不成功,则返回失败
- 服务器异常
- 可忽略行为 - 前台忽略改行为继续流程
- 服务器一时繁忙 - 前台再次按照原有参数进行再次请求
- 服务器操作数异常 - 前台再次采集操作数,重新发送请求
- 服务器错误 - 不可继续运行的错误,前台继续执行会造成 ‘crash’ ,并且当前操作流程已经出现了中断,返回首页或者中端当前操作流程,返回到起始位置
微信提供了基础 request 方法,该方法的使用方式和大多数框架提供的 ajax 方式类似
https://developers.weixin.qq.com/miniprogram/dev/api/network-request.html#wxrequestobject
对比其与 jquery 方法他们的可选参数
$.ajax({
url, // 请求路径,微信中名为 path
data, // 请求参数,微信中同名,参数可以是 object / string / arrayBuffer
type, // post | get,微信中名为 method
complete,// xhr, status 请求完成函数,微信中同名
success, // 当请求成功,参数 result, status, xhr;微信中具有同名函数,使用 res 对象封装 result,status,xhr等信息,具体为 { data, statusCode, header }
error, // xhr, status, error,微信中命名为 fail,同样使用 res 封装参数信息
jsonp, // 重写回调函数的字符串,微信中为 dataType,参数只有 json 或者 null
timeout, // 本地超时时间 - 微信中放置在 app.json 文件中
contentType :// 指定发送内容类型值,默认使用 "application/x-www-form-urlencoded",微信在此处对该参数进行拆解处理,并且将其封装成了 header 方法,该方法可以提供自定义 header 属性,参数是 object;微信默认 'application/json' - body : raw 格式
dataFilter, //
async, // 异步同步控制
beforeSend, // 在请求执行前
cache, // 是否缓存页面请求
context, // 为所有相关 ajax 规定 this 值
})
经过比对发现,微信 request 的请求可选参数还是尽可能的简化和抽象了 ajax 的一些繁琐结构,特别是 header 的使用上。将一些意义不明确的参数重新命名也看出微信团队在设计微信小程序时,有着大量 h5 等 web 应用开发的经验作为参考。
请求处理层次
- 直接使用地方 target_request
- 一次 http 处理
- http 协议层
- 自定义协议层
划分层次方式
- 对复用的原始函数进行包装
- 在复用函数结构中进行层次划分
- 由软件(编码)设计者将模块抽象成
- 传入
- 业务
- 传出
- 由软件(编码)设计者将模块抽象成
-
- 抽离出来的传入和传出层做统一处理
- 如果业务端有复用,则可以再次进行抽象
微信 request 处理方法:
微信处在处理请求过程中,重要的三个返回事件:
1. success
2. fail
3. complete
代码示例:
// 构造对象方式使用
function wx_auto_request(config){
// 内部记录
let request_time = 0; // 记录请求次数
let request_options; // 记录当前请求的参数
// 封装微信请求方法
function request(options) {
let _opts = {}; // 原始 wx.request 可选参数
let timer; // 定时器句柄
// 自定义协议错误码处理方式 - 该处使用 数组游标 定义错误码
// 该种形式错误码可以不断进行累进,但是不能进行错误分类(无权码)
let ErrCode = [
// 错误码 0
{
rep: function () {
// 封装在对象中,可以直接进行错误处理
if(config.errCoed0){
config.errCoed0();
}
return false; // 返回 false 则使用 if 忽略
}
},
// 错误码 1
{
rep: function () {
request_time = 0; // 清楚迭代游标
request_options = options; // 记录当前操作数
request(request_options); // 进行一次迭代
// 再次注意,错误处理的位置,应该在内部的某些记录变化后执行
if(config.errCoed1){
config.errCoed1();
}
return true; // 不进行忽略操作,忽略操作时在 判断中做 return 操作,中断之后的操作。
}
},
// 错误码 2
{
rep: function () {
request_time = 1; // 错误码进行再次请求,游标设置为 1,最大值为 2
wx.hideLoading();
wx.showToast({
title: "请求重试",
icon: "none",
duration: 1000
})
if(config.errCoed2){
config.errCoed2();
}
/*** 以下是自定义错误处理 ***/
// 返回首页
setTimeout(function () {
wx.reLaunch({
url: '/pages/main',
})
}, 1100);
/*** 以上为自定义错误处理 ***/
return true;
}
}
]
// 重构 wx.request 选择参数
for (let k in options) {
// 特殊化的 success , fail 和 complete 单独拿出来处理
if (k == 'success' || k == 'fail' || k == 'complete') {
break;
}
_opts[k] = options[k];
}
// 重点处理 success 和 fail 方法
_opts['success'] = function (d) {
// 成功请求清空 timer,该方法可以直接使用,不用做 timer 是否为 interval判断
clearTimeout(timer);
// 隐藏 loading
wx.hideLoading();
// 判断是否含有自定义协议部分
if (typeof d.errCode != 'undefined') {
// 判断是否具有该错误码
if (ErrCode[d.errCode] != undefined) {
// 是否可以忽略该错误码继续执行
if (ErrCode[d.errCode].rep()) return;
}
}
// 可选参数,是否处理或者接收返回结果,回调函数
if (typeof options.success != 'undefined') {
options.success(d);
}
}
// 微信小程序原生错误处理
_opts['fail'] = function (err) {
// 自动进行两次再请求操作,超过则提示错误
if (request_time < 2) {
request_time++; // 游标自增
return request(options); // 原参数迭代
} else {
if (typeof options.fail != 'undefined') {
options.fail(err);
}
// 重置对象记录,并且提示错误
request_time = 0;
wx.hideLoading();
wx.showToast({
title: "连接错误,请稍后重试",
icon: "none",
duration: 1100
})
/*** 自定义基础错误,程序无法继续进行访问 ***/
setTimeout(function () {
wx.reLaunch({
url: '/pages/main',
})
}, 1200);
return;
}
};
// 请求前定时器,如果到了设置时间,则产生 loading 加载中提示效果
timer = setTimeout(function () {
wx.showLoading({
title: '加载中'
})
}, 4000)
// 最后执行微信 request 操作
wx.request(_opts);
};
return request;
}
示例小程序: