最近在开发微信小程序, 在测试时, 总能碰到一些诸如网络被打断啊之类的问题. 小程序是一款实时互动的小程序, 基于一系列原因, 没有使用Socket, 而是使用的是长链接. 所以对这类问题不能大意啊, 一个请求断了, 后面的实时状态就无从谈起了.

  最简单的啊, 就是对这个长链接捕获错误, 然后重试呗! 当然, 实现这个很简单, 没两行代码就搞定了. 我还做了断网之类的验证, 单单规避这个长链接的错误, 完全OK的.

  但是还有很多其他请求哇, 做断网重连的测试的时候, 能导致一些其他未知的影响(当然,不断网的情况下这些是不存在的), (个人处女座, 追求完美)于是我就决定从网络请求的底层, 写入重试机制.

  整个项目是Web短和小程序端的实时互动, 为了公用一套类库, 我对所有Web和小程序端的底层接口都做了封装, 以达到公用类库的目的, 而重试机制我只准备给小程序做, Web端是内部使用的, 出现极端情况, 让他刷新一下咯, 而且这种概率很小, 就不考虑了.

  首先描述一下我的重试机制的思路, 当任何一个请求发生错误之后, 进行捕获, 进行十次重试, 每次的时间间隔都比上次长, 十次之后, 提示用户网络故障是否要重试, 用户点是之后会再次重试十次, 依次规律, 直至网络请求成功.

const _retryTimes: number = 10;
class JeResolve {
protected promise: Promise<NetRes<any>>
protected _resolve: (value: NetRes<any>) => void | PromiseLike<void>;
protected _reject: (reason: any) => void;
protected reqOptions: RequestOptions;
protected requestObj: RequestTask; protected Listener: JeSysListener = new JeSysListener(this); constructor() {
this.promise = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});
} request<T>(options?: RequestOptions | undefined): IResolve<T> {
if (options) {
this.retryTimes = 0;
options.url = commonService.getUrl(options.url);
this.reqOptions = options;
this.reqOptions.success = (res: any) => {
this.Listener.UnListen();
this._resolve(res);
};
this.reqOptions.fail = (res: any) => {
if (this.retryTimes < _retryTimes) {
this.retryTimes++;
if (!this.isAbort) {
setTimeout(() => {
if (this.retryTimes < _retryTimes + 1 && !this.isAbort) {
this.requestObj = uni.request(this.reqOptions);
}
}, 100 * this.retryTimes);
}
} else {
systemService.raiseRetryTimedout();
}
};
this.requestObj = uni.request(this.reqOptions);
}
return this;
} resolve<T>(call: (res: T) => void): IAbort {
this.promise.then(res => {
call(res.data);
});
return this;
} abort() {
this.Listener.UnListen();
this.requestObj.abort();
this.isAbort = true;
} protected retryTimes: number = 0;
protected isAbort: boolean = false;
onRetryedSuccess(event: SysEvent): void {
this.retryTimes = 0;
this.requestObj = uni.request(this.reqOptions);
} onRetryedTimesout(event: SysEvent): void {
this.retryTimes = _retryTimes;
}
}

以上是我基于Promise自己封装的请求类, 上面很容易看懂, 最底下两个方法解释一下, 是自己分封装的全局的事件的触发以及监听.
主要逻辑:
  1、当某个请求重试超过十次之后触发请求超时的事件, 全局会对事件进行一个过滤, 上次事件没有被用户反馈之前, 多个请求接连触发超时会自动过滤掉.
  2、在用户点击确定重试之后, 会触发一个确定重试的事件, 所有失败的请求都能监听到这个事件, 开始新的十次重试.
觉得这个挺好玩的, 才写出来, 还不够完善, 感兴趣的道友批评指正.

微信小程序的网络重试机制的更多相关文章

  1. 微信小程序开发心得--动画机制

    微信小程序也已出来有一段时间了,最近写了几款微信小程序项目,今天来说说感受.首先开发一款微信小程序,最主要的就是针对于公司来运营的,因为,在申请appid(微信小程序ID号)时候,需要填写相关的公司认 ...

  2. 微信小程序的网络设置,及网络请求:wx.request(OBJECT)

    Md2All 一个Markdown在线转换工具 网址:http://md.aclickall.com 微信公众号:颜家大少本文所用排版工具:http://md.aclickall.com 支持通用的M ...

  3. 微信小程序的加载机制和运行机制

    一.运行机制 冷启动指的是重新启动,热启动指的是5分钟内从后台切换到前台,只有冷启动才能加载最新的包. 小程序什么时候会关闭? 5min后台运行,连续收到两次(2s)系统告警. 二.加载机制 三.小程 ...

  4. 微信小程序 --- 获取网络状态

    获取网络状态:wx.getNetworkType btnclick:function(){ wx.getNetworkType({ success:function(res){ console.log ...

  5. 微信小程序 API 网络(ajax)

    网络 API 类似于 ajax 向服务器请求网络地址,唯一不同的是这个请求有很多的规则,且必须向服务器上请求,不能在本地请求 网络 发送请求: wx.request() 发起https网络请求 参数: ...

  6. 微信小程序网络封装-简单高效

    废话引言 小程序虽然出世很久了,但一直没怎么接触到小程序开发.吉他兴趣班老师想弄一个小程序发布课程信息和打卡功能,作为IT一员就自愿加入了这个小程序开发小组中.虽然小程序面向的是前端工程师,但作为移动 ...

  7. 微信小程序学习指南

    作者:初雪链接:https://www.zhihu.com/question/50907897/answer/128494332来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  8. [转]微信小程序安全浅析

    本文转自:http://blog.csdn.net/baize_security/article/details/54582854 引言 近期微信小程序重磅发布,在互联网界掀起不小的波澜,已有许多公司 ...

  9. 微信小程序从开发到上线流程

    一.微信小程序从开发到上线流程 注册小程序 1.登录微信公众平台 https://mp.weixin.qq.com 2.在微信公众平台>立即注册>小程序中注册微信小程序 3.在邮箱中激活并 ...

随机推荐

  1. Luogu4688 [Ynoi2016]掉进兔子洞 【莫队,bitset】

    题目链接:洛谷 我们知道要求的是\([l_1,r_1],[l_2,r_2],[l_3,r_3]\)的可重集取交的大小,肯定是要用bitset的,那怎么做可重集呢? 那就是要稍微动点手脚,首先在离散化的 ...

  2. 数据结构实验之图论九:最小生成树 (SDUT 2144)

    #include<bits/stdc++.h> using namespace std; typedef long long ll; struct node { int s, e; int ...

  3. (7)打造简单OS-加载内核

    一.简要说明 我们在第五讲[(5)打造简单OS-进入保护模式]中的mbr.S 汇编文件有段这样的代码 mov eax, 0x2 ; 起始扇区lba地址,从间隔第二个扇区开始 mov bx, 0x900 ...

  4. ROS与树莓派的结合

    从零开始学树莓派和ROS 今天写下自己的第一篇博客,记录一下自己的学习历程和学习过程中碰到的各种小问题,供同道者参阅和自己以后回顾用 ,水平不高,我就放开手写吧,反正也不会有人看. 我现在在做毕业设计 ...

  5. CF1174F Ehab and the Big Finale(交互+剖分)

    做法 \(x\)为隐藏节点,\(dep_x=d(1,x)\) \((1)\):\(u=1\) \((2)\):重链剖分,比如\(v\)为\(u\)的重链底部,查询\(dis(x,v)\)的长度,\(y ...

  6. (转)hadoop 集群常用端口

    转载于:https://www.cnblogs.com/liying123/p/7097806.html hadoop集群的各部分一般都会使用到多个端口,有些是daemon之间进行交互之用,有些是用于 ...

  7. 在取变量名的时候,千万不要用new

    这样子是会报错的

  8. meshing-划分圆柱结构化网格

    原视频下载地址:https://yunpan.cn/cqjeckrzEpVkY  访问密码 eb5d

  9. Qt 的插件制作

    首先会遇到一些插件使用的问题: 插件加载的时候出现乱码 qrc:/main.qml:20: Error: Qt.createQmlObject(): failed to create object: ...

  10. Spring源代码分析:PropertiesLoaderSupport

    概述 Spring PropertiesLoaderSupport是一个抽象基类,它抽象了从不同渠道加载属性的通用逻辑,以及这些属性应用优先级上的一些考虑.它所提供的这些功能主要供实现子类使用.Spr ...